使用相同的URL处理两个不同的页面

I'm working on a program that automatically logs into a site using Selenium. In some situations, if the site doesn't remember the browser, it will ask you to answer a secret question before it takes you to the password page. Originally I thought I would just handle this with an If statement that checks the current URL against the specific URL that I knew was produced when I was directed to the secret question page. The issue I'm running into, is that the URL for the secret question page, and the URL for the password page are the same. Is there a way to differentiate these two pages by the URL in this situation, or will I need to find an alternative method?

If the URLs are exactly the same, you won't have any differences to compare, so you won't be able to tell what the page content is based on the URL.

It's common to have one page, with one URL, that shows different content, determined by backend code that Selenium can't see. You will need to compare something that is different between the two pages, such an element which only appears on one page.

Presuming that you don't care whether a password or secret question is shown, you just want Selenium to get through the login process, an easy solution is to use an if / else statement to check which form appears and then attempt to fill out the form that is present.

if ($this->isElementPresent($password_form)) {
    // enter the password;
} elseif ($this->isElementPresent($secret_question)) {
    // answer the secret question;
} else {
    throw new Exception('Could not find password form or secret question on the login page. [url]');
}

The actual form element most likely has a different ID or name for each form that you can use for identification, or the input for password/secret answer will have different names. (If all else fails, you can look for the text on the page which says whether to enter a password or secret question.)

Waaiit a miiinuute. You got it all wrong.

When writing the tests you should have a clearly defined (expected) output/behaviour for the same input.

So, in your case, you should have 2 tests:

  • do all the things required to make your app forgets the browser (clear cookies, change browser signature, etc) and check that your getting the 'secret question' page
  • do all the things required to make sure your request represents a known browser and check you're on the login page

Something like

testLogin_unknownBrowser_showsSecretQuestion:
    ->clearCookies
    ->findElement(byId 'secretQuestion')

testLogin_knownBrowser_showsLogin:
    ->setCookies
    ->findElement(byId 'username')
    ->findElement(byId 'password')

At this point it's easy to figure out the problem if one of your tests fails.

Ideally you don't include any magic and keep your tests as clear as possible.

You might want to abstract the 'do all the things to login' in a BaseTestCase and use that in multiple cases when you just want to login and test something else without constantly solving the 'what screen did I got' issue.