Skip to content

Commit 6097db6

Browse files
committed
Only wait until element appears & fractional waits
1 parent 40eed99 commit 6097db6

File tree

2 files changed

+69
-5
lines changed

2 files changed

+69
-5
lines changed

src/Context/BrowserContext.php

+60-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
use Behat\Mink\Exception\ExpectationException;
77
use Behat\Mink\Exception\ResponseTextException;
88
use Behat\Mink\Exception\ElementNotFoundException;
9+
use WebDriver\Exception\StaleElementReference;
10+
use Behat\Behat\Tester\Exception\PendingException;
911

1012
class BrowserContext extends BaseContext
1113
{
1214
private $timeout;
1315
private $dateFormat = 'dmYHi';
16+
private $timerStartedAt;
1417

1518
public function __construct($timeout = 1)
1619
{
@@ -25,6 +28,16 @@ public function closeBrowser()
2528
$this->getSession()->stop();
2629
}
2730

31+
/**
32+
* @BeforeScenario
33+
*
34+
* @When (I )start timing now
35+
*/
36+
public function startTimer()
37+
{
38+
$this->timerStartedAt = time();
39+
}
40+
2841
/**
2942
* Set login / password for next HTTP authentication
3043
*
@@ -164,21 +177,35 @@ public function iWaitUntilISee($text)
164177
*/
165178
public function iWaitSecondsUntilISeeInTheElement($count, $text, $element)
166179
{
180+
$startTime = time();
167181
$this->iWaitSecondsForElement($count, $element);
168182

169183
$expected = str_replace('\\"', '"', $text);
170-
$node = $this->getSession()->getPage()->find('css', $element);
171184
$message = "The text '$expected' was not found after a $count seconds timeout";
172185

173-
$this->assertContains($expected, $node->getText(), $message);
186+
$found = false;
187+
do {
188+
try {
189+
usleep(1000);
190+
$node = $this->getSession()->getPage()->find('css', $element);
191+
$this->assertContains($expected, $node->getText(), $message);
192+
return;
193+
}
194+
catch (ExpectationException $e) {
195+
/* Intentionaly leave blank */
196+
}
197+
catch (StaleElementReference $e) {
198+
// assume page reloaded whilst we were still waiting
199+
}
200+
} while (!$found && (time() - $startTime < $count));
174201
}
175202

176203
/**
177204
* @Then (I )wait :count second(s)
178205
*/
179206
public function iWaitSeconds($count)
180207
{
181-
sleep($count);
208+
usleep($count * 1000000);
182209
}
183210

184211
/**
@@ -213,6 +240,7 @@ public function iWaitSecondsForElement($count, $element)
213240

214241
do {
215242
try {
243+
usleep(1000);
216244
$node = $this->getSession()->getPage()->findAll('css', $element);
217245
$this->assertCount(1, $node);
218246
$found = true;
@@ -221,7 +249,7 @@ public function iWaitSecondsForElement($count, $element)
221249
/* Intentionnaly leave blank */
222250
}
223251
}
224-
while (time() - $startTime < $count);
252+
while (!$found && (time() - $startTime < $count));
225253

226254
if ($found === false) {
227255
$message = "The element '$element' was not found after a $count seconds timeout";
@@ -376,4 +404,32 @@ public function switchToMainFrame()
376404
{
377405
$this->getSession()->switchToIFrame();
378406
}
407+
408+
/**
409+
* test time from when the scenario started
410+
*
411+
* @Then (the )total elapsed time should be :comparison than :expected seconds
412+
* @Then (the )total elapsed time should be :comparison to :expected seconds
413+
*/
414+
public function elapsedTime($comparison, $expected)
415+
{
416+
$elapsed = time() - $this->timerStartedAt;
417+
418+
switch ($comparison) {
419+
case 'less':
420+
$this->assertTrue($elapsed < $expected, "Elapsed time '$elapsed' is not less than '$expected' seconds.");
421+
break;
422+
423+
case 'more':
424+
$this->assertTrue($elapsed > $expected, "Elapsed time '$elapsed' is not more than '$expected' seconds.");
425+
break;
426+
427+
case 'equal':
428+
$this->assertTrue($elapsed === $expected, "Elapsed time '$elapsed' is not '$expected' seconds.");
429+
break;
430+
431+
default:
432+
throw new PendingException("Unknown comparison '$comparison'. Use 'less', 'more' or 'equal'");
433+
}
434+
}
379435
}

tests/features/browser.feature

+9-1
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ Feature: Browser Feature
6262
@javascript
6363
Scenario: Wait before seeing
6464
Given I am on "/browser/timeout.html"
65-
Then I wait 3 seconds until I see "timeout"
65+
When I wait 3 seconds until I see "timeout"
6666
And I wait 1 second
6767
And I wait for "#iframe" element
6868
And I wait 5 seconds for "#iframe" element
69+
Then the total elapsed time should be less than 6 seconds
6970

7071
@javascript
7172
Scenario: Check element visibility
@@ -83,3 +84,10 @@ Feature: Browser Feature
8384
Scenario:
8485
Given I am on "/browser/elements.html"
8586
Then i save the value of "today" in the "today" parameter
87+
88+
Scenario: Waiting for fractions of a second
89+
Given I am on "/browser/index.html"
90+
And I wait 1.9 seconds
91+
And I wait 1.9 seconds
92+
And I wait 1.9 seconds
93+
Then the total elapsed time should be more than 4 seconds

0 commit comments

Comments
 (0)