使用Selenium使用测试帐户登录Facebook

时间:2012-12-20 00:50:00

标签: php facebook facebook-graph-api selenium selenium-webdriver

我有一些PHP代码,使用图形api在我的应用程序中创建一个Facebook测试帐户。我已经测试了这个代码,它运行正常。

我在使用Selenium Webdriver (for PHP)作为测试用户登录Facebook时遇到了麻烦。

以下是我的代码的简化版本:

class FB_OAuthTest extends PHPUnit_Framework_TestCase {
    private $fbUtils = null;
    private $fbUser = null;
    private $startUrl = 'http://my.start.page';

    protected function setUp() {
        $this->webdriver = new WebDriver(Config::SELENIUM_SERVER, Config::SELENIUM_PORT);
        $this->webdriver->connect(Config::BROWSER);

        $this->fbUtils = new FBUtils(Config::FB_APP_ID, Config::FB_APP_SECRET);

        // create new FB test user here
        $this->fbUser = $this->fbUtils->createNewTestUser();
    }

    protected function tearDown() {
        // delete the test user when we're done
        if($this->fbUser != null) {
            $this->fbUtils->deleteTestUser($this->fbUser->id);
        }
        $this->webdriver->close();
    }

    // the magic happens here
    public function testOAuth() {    
        // "login" as test user by requesting the login url that they give
        $this->webdriver->get($this->fbUser->login_url);

        // start the app workflow: go to a page with a FB OAuth button
        $this->webdriver->get($this->startUrl); 
        $this->assertTrue(isTextPresent("FB_OAuth_Test_Start", $this->webdriver));

        // click the button to begin the FB OAuth process
        $oAuthButton = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//button[@control='FBLogin1']");
        $oAuthButton->click();

        // The Facebook login/OAuth dialog shows up now, and forces me to login
        // despite first going to the FB user's login url

        // sleep for the hell of it, just to make sure the FB login dialog loads
        sleep(5);

        // Selenium fails here - not finding the input with id='email', despite it existing on the page
        $emailField = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[id='email']");
        if ($emailField) {
            $emailField->sendKeys(array($this->fbUser->email));
            $emailField->submit();
        } else {
            $this->fail('FB login email field not found');
        }

        $passwordField = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[id='pass']");
        if ($passwordField) {
            $passwordField->sendKeys(array($this->fbUser->password));
            $passwordField->submit();
        } else {
            $this->fail('FB login password field not found');
        }

        $loginButton = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[name='login']");
        if ($loginButton) {
            $loginButton->click();
        } else {
            $this->fail('FB login button not found');
        }

        $grantAppPermission = $this->webdriver->findElementBy(LocatorStrategy::name, "grant_clicked");
        $grantAppPermission->click();

        $this->assertTrue(isTextPresent("FB_OAuth_Test_Success", $this->webdriver));
    }
}

从代码注释中可以看出,Selenium找不到'email'输入元素,测试失败。任何想法将不胜感激。谢谢!

更新

我甚至尝试过一些相当直接的东西,比如代码打击,但它仍然不起作用。

private function loginToFacebook() {
    $this->webdriver->get('https://www.facebook.com/login.php?login_attempt=1');

    sleep(1);

    $emailField = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[id='email']");
    if ($emailField) {
        $emailField->sendKeys(array($this->fbUser->email));
        $emailField->submit();
    } else {
        $this->fail('FB login email field not found');
    }

    $passwordField = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[id='pass']");
    if ($passwordField) {
        $passwordField->sendKeys(array($this->fbUser->password));
        $passwordField->submit();
    } else {
        $this->fail('FB login password field not found');
    }

    $loginButton = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[name='login']");
    if ($loginButton) {
        $loginButton->click();
    } else {
        $this->fail('FB login button not found');
    }
}

更新:这是工作代码

private function loginToFacebook() {
    $this->webdriver->get('https://www.facebook.com/login.php?login_attempt=1');

    $emailField = $this->webdriver->findElementBy(LocatorStrategy::id, 'email');
    if ($emailField) {
        $emailField->sendKeys(array($this->fbUser->email));
    } else {
        $this->fail('FB login email field not found');
    }

    $passwordField = $this->webdriver->findElementBy(LocatorStrategy::id, 'pass');
    if ($passwordField) {
        $passwordField->sendKeys(array($this->fbUser->password));
    } else {
        $this->fail('FB login password field not found');
    }

    $loginButton = $this->webdriver->findElementBy(LocatorStrategy::xpath, "//input[@name='login']");
    if ($loginButton) {
        $loginButton->click();
    } else {
        $this->fail('FB login button not found');
    }
}

1 个答案:

答案 0 :(得分:2)

您错误地定义了ur xpath表达式

应该是//input[@id='email'] ##Note the @ sign (not sure you need to escape '@' with a blackslash)

但是,尝试更改您尝试查找网络元素的方式

 // try locating by LocatorStrategy id
        $emailField = $this->webdriver->findElementBy(LocatorStrategy::id, 'email');
        if ($emailField) {
            $emailField->sendKeys(array($this->fbUser->email));
            $emailField->submit();
        } else {
            $this->fail('FB login email field not found');
        }

id相比,namexpath搜索速度更快。

对密码字段进行相同的更改,如此

$passwordField = $this->webdriver->findElementBy(LocatorStrategy::id, "pass");