phpunit-selenium
phpunit-selenium copied to clipboard
Can not pass a string parameter to waitUntil() method?
Hi guys, I want to encapsulate a method for finding elements with waitUntil() method, after reading samples here , I tried several times as following:
Code1:
public function findElement($elementCssPath){
$this->waitUntil(function($testCase) {
try {
$testCase->byCssSelector($elementCssPath);
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
return TRUE;
}
}, 8000);
}
btw: where does this $testcase variable come from?
Code2:
public function findElement($elementCssPath){
$this->waitUntil(function () {
if ($this->byCssSelector($elementCssPath)) {
return true;
}
return null;
}, 20000);
}
Code3:
public function findElement($elementCssPath){
$this->waitUntil(function($elementCssPath) {
try {
$this->byCssSelector($elementCssPath);
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
return TRUE;
}
}, 8000);
}
But all of them reported an error: Undefined variable: elementCssPath I searched a lot on internet ,but there's no further information. Please help ,thanks!
It's not a phpunit-selenium issue. You are just using closures the wrong way ;)
Try
$this->waitUntil(function($testCase) use ($elementCssPath) {
...
});
With the "use" part, you are allowed to use $elementCssPath within the closure scope. The $testCase parameter ist the current TestCase and is passed in by phpunit-selenium at call-time.
Edit: Btw. what do you mean by "finding elements"? To find an element, you can simply use
$this->byCssSelector($elementCssPath)
When you set an implicit wait with
$this->timeouts->implicitWait($timeout)
then selenium will even wait for the element to appear. So for normal cases, there is no need for an explicit waitUntil.
@julianseeger Thank you very much for so detailed answer.
I've set an implicit wait , and it works nicely. To encapsulate a waitUntil method is just in case of possible requirements. By "finding elements" I mean,using waitUntil method to prejudge whether the element exist or it's already clickable , if it appears, then locate it with By methods.
This code works for me:
public function findElementWaitUntil($elementCssPath){
$this->waitUntil(function() use($elementCssPath){
if ($this->byCssSelector($elementCssPath)) {
return true;
}
return null;
}, 10000);
try{
$object=$this->byCssSelector($elementCssPath);
return $object;
}
catch(Exception $e){
throw $e;
}
}
This code always reported a time-out error: “PHPUnit_Extensions_Selenium2TestCase_WebDriverException: Timed out after 10 seconds”
public function findElementWaitUntil($elementCssPath){
$this->waitUntil(function($testcase) use($elementCssPath){
try {
$testcase->byCssSelector($elementCssPath);
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
return TRUE;
}
}, 10000);
//or like this
//$this->waitUntil(function() use($elementCssPath){
//try {
// $this->byCssSelector($elementCssPath);
//} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
// return TRUE;
// }
// }, 10000);
try{
$object=$this->byCssSelector($elementCssPath);
return $object;
}
catch(Exception $e){
throw $e;
}
}
IIRC, waitUntil wants you to return something that is not null and you can directly use that result:
public function findElementWaitUntil($elementCssPath) {
return $this->waitUntil(
function (PHPUnit_Extensions_Selenium2TestCase $testCase) use ($elementCssPath) {
return $testCase->byCssSelector($elementCssPath);
},
10000
);
}
so there is no need for selecting it twice, iirc ;)