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

Php 使用Selenium使用测试帐户登录Facebook,php,facebook,facebook-graph-api,selenium,selenium-webdriver,Php,Facebook,Facebook Graph Api,Selenium,Selenium Webdriver,我有一些PHP代码,可以使用GraphAPI在我的应用程序中创建Facebook测试帐户。我已经测试了这段代码,它运行良好 我作为测试用户登录Facebook时遇到了问题 以下是我的代码的简化版本: class FB_OAuthTest extends PHPUnit_Framework_TestCase { private $fbUtils = null; private $fbUser = null; private $startUrl = 'http://my.st

我有一些PHP代码,可以使用GraphAPI在我的应用程序中创建Facebook测试帐户。我已经测试了这段代码,它运行良好

我作为测试用户登录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');

    $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');
    }
}
我甚至尝试过做一些相当直接的事情,比如代码吹,但仍然不起作用

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表达式

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

但是,尽管如此,还是要尝试改变查找web元素的方式

 // 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
name
进行搜索比通过
xpath
进行搜索更快

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


$passwordField=$this->webdriver->findElementBy(LocatorStrategy::id,“pass”)

facebook登录页面是否作为弹出窗口打开?我设置了OAuth,使其不会作为弹出窗口打开,而是在同一页面上打开。此外,如果我在底部使用loginToFacebook()方法,Facebook登录页面会显示得很好。真不敢相信我错过了,谢谢!我明天回去工作的时候会试试,试试看。不幸的是,Facebook.com在输入字段上没有@id属性,所以我必须使用这个xpath策略。对于这些测试,我认为慢是可以的,因为它们是浏览器测试,不会经常运行。这很有效,谢谢!我还做了一些愚蠢的事情,比如在将内容发送到密码字段后立即调用
submit()
。很好,它成功了。我还非常确信,您将能够根据
id
找到您的元素。无论如何,一切都好。