phpunit-selenium icon indicating copy to clipboard operation
phpunit-selenium copied to clipboard

Can not pass a string parameter to waitUntil() method?

Open cobraBJ opened this issue 11 years ago • 3 comments

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!

cobraBJ avatar Mar 11 '14 04:03 cobraBJ

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 avatar Mar 11 '14 18:03 julianseeger

@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;
        }   
    }

cobraBJ avatar Mar 12 '14 01:03 cobraBJ

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 ;)

julianseeger avatar Mar 12 '14 06:03 julianseeger