Skip to content

Commit 98901d4

Browse files
Add waitForEvent() method (#972)
* Add waitForEvent This commit adds a `waitForEvent()` method to the `WaitsForElements` trait, making it available to the `Browser` class. The `waitForEvent()` method pauses the test execution until a given event `type` occurs on a `target` element or object. It also adds a corresponding test case to `WaitsForElementsTest`. * Fix syntax in exception message * formatting Co-authored-by: Taylor Otwell <[email protected]>
1 parent ea9a455 commit 98901d4

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/Concerns/WaitsForElements.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Closure;
77
use Exception;
88
use Facebook\WebDriver\Exception\NoSuchElementException;
9+
use Facebook\WebDriver\Exception\ScriptTimeoutException;
910
use Facebook\WebDriver\Exception\TimeOutException;
1011
use Facebook\WebDriver\WebDriverExpectedCondition;
1112
use Illuminate\Support\Arr;
@@ -343,6 +344,38 @@ public function clickAndWaitForReload($selector = null)
343344
});
344345
}
345346

347+
/**
348+
* Wait for the given event type to occur on a target.
349+
*
350+
* @param string $type
351+
* @param string|null $target
352+
* @param int|null $seconds
353+
* @return $this
354+
*
355+
* @throws \Facebook\WebDriver\Exception\TimeOutException
356+
*/
357+
public function waitForEvent($type, $target = null, $seconds = null)
358+
{
359+
$seconds = is_null($seconds) ? static::$waitSeconds : $seconds;
360+
361+
if ($target !== 'document' && $target !== 'window') {
362+
$target = $this->resolver->findOrFail($target ?? '');
363+
}
364+
365+
$this->driver->manage()->timeouts()->setScriptTimeout($seconds);
366+
367+
try {
368+
$this->driver->executeAsyncScript(
369+
'eval(arguments[0]).addEventListener(arguments[1], () => arguments[2](), { once: true });',
370+
[$target, $type]
371+
);
372+
} catch (ScriptTimeoutException $e) {
373+
throw new TimeoutException("Waited {$seconds} seconds for event [{$type}].");
374+
}
375+
376+
return $this;
377+
}
378+
346379
/**
347380
* Wait for the given callback to be true.
348381
*

tests/WaitsForElementsTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,4 +324,23 @@ public function test_wait_for_reload()
324324

325325
$browser->waitForReload();
326326
}
327+
328+
public function test_wait_for_event()
329+
{
330+
$driver = m::mock(stdClass::class);
331+
$driver->shouldReceive('manage->timeouts->setScriptTimeout')->with(3);
332+
$driver->shouldReceive('executeAsyncScript')->with(
333+
'eval(arguments[0]).addEventListener(arguments[1], () => arguments[2](), { once: true });',
334+
['body form', 'submit']
335+
);
336+
337+
$resolver = m::mock(stdClass::class);
338+
$resolver->shouldReceive('findOrFail')
339+
->with('form')
340+
->andReturn('body form');
341+
342+
$browser = new Browser($driver, $resolver);
343+
344+
$browser->waitForEvent('submit', 'form', 3);
345+
}
327346
}

0 commit comments

Comments
 (0)