php - 使用 Selenium 通过测试帐户登录 Facebook

标签 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');
    }
}

最佳答案

您的 xpath 表达式定义不正确

应该是//input[@id='email'] ##注意@符号(不确定是否需要用黑斜杠转义'@')

但尽管如此,请尝试改变定位网络元素的方式

 // 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');
        }

xpath相比,通过idname搜索速度更快。

对密码字段进行相同的更改,如下所示

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

关于php - 使用 Selenium 通过测试帐户登录 Facebook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13963682/

相关文章:

java - 将多个视频无缝拼接在一起

javascript - 从 Facebook 帖子上的 Chrome 扩展触发 React 组件的状态更改

facebook - 如何使用图形 API 从 Facebook 群组检索照片?

debugging - 你如何调试你的 facebook 应用程序?

iphone - 如何发布到 friend 的时间轴

javascript - Facebook all.js 和 sdk.js 的区别

php - 使用php连接mongodb的字段

php - 如何修复此 'Call to a member function row() on boolean' 错误?

php - jquery $.post 和 php $_POST

ios - Facebook Audience Network 频繁加载错误