Well I wasn’t sure about having a catch without a throw so that was confusing me but I see that you were correct in having the sleep() function outside the catch brackets. Don’t know what I was thinking there.
I just realized that the element "id=ContactForm_body_em_" is always present because it is hard coded so it should break from the loop regardless of whether the text "Body cannot be blank." exists. If I navigate to the contact form and view source without submitting this is already there.
<div class="errorMessage" id="ContactForm_body_em_" style="display:none"></div>
So, the element is found and it breaks from the loop immediately. The element exists but the text doesn’t.
I tried replacing the check for the element with the check for the text and it just sits there going through the loop never finding the text.
I think it is some issue with javascript because if I disable javascript, submit the form and then view source I see this
<div class="errorMessage" id="ContactForm_body_em_">Body cannot be blank.</div>
But with javascript enabled I see this
<div class="errorMessage" id="ContactForm_body_em_" style="display:none"></div>
Update: I found another post
http://www.yiiframework.com/forum/index.php?/topic/17981-selenium-tests-fail-in-new-117-webapp/
It was definitely caused by javascript validation. Confusing that it’s still a problem and the javascript seems to be still working when disabled client side but ok, sleep() fixes the issue. I just didn’t need to loop and check for isElementPresent().
A simple sleep before each failing assertion fixes it.
public function testContact()
{
$this->open('?r=site/contact');
$this->assertTextPresent('Contact Us');
$this->assertElementPresent('name=ContactForm[name]');
$this->assertElementPresent('id=ContactForm_body_em_');
$this->type('name=ContactForm[name]','tester');
$this->type('name=ContactForm[email]','tester@example.com');
$this->type('name=ContactForm[subject]','test subject');
$this->click("//input[@value='Submit']");
sleep(1);
$this->assertTextPresent('Body cannot be blank.');
}
public function testLoginLogout()
{
$this->open('');
// ensure the user is logged out
if($this->isTextPresent('Logout'))
$this->clickAndWait('link=Logout (demo)');
// test login process, including validation
$this->clickAndWait('link=Login');
$this->assertElementPresent('name=LoginForm[username]');
$this->type('name=LoginForm[username]','demo');
$this->click("//input[@value='Login']");
sleep(1);
$this->assertTextPresent('Password cannot be blank.');
$this->type('name=LoginForm[password]','demo');
$this->clickAndWait("//input[@value='Login']");
$this->assertTextNotPresent('Password cannot be blank.');
$this->assertTextPresent('Logout');
// test logout process
$this->assertTextNotPresent('Login');
$this->clickAndWait('link=Logout (demo)');
$this->assertTextPresent('Login');
}
}
I guess it pretty evident of the problem now, that all the other assertTextPresent tests that pass are checking for hard coded text rather than javascript text and that’s why they pass.
Thank you Windsor for pointing out the main trouble maker(javascript) and the sleep() fix even if I didn’t need the loop part.