Skip to content

Commit

Permalink
[1.10] Allow usage of XPath in waitForElement (#544)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonas Hoopmann <[email protected]>
Co-authored-by: Graham Campbell <[email protected]>
  • Loading branch information
3 people authored Sep 8, 2023
1 parent d90baea commit d45e130
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 6 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,29 @@ $page->navigate('http://example.com')->waitForNavigation();
$elem = $page->dom()->search('//div/*/a');
```

Wait for an element by CSS selector:

```php
$page = $browser->createPage();
$page->navigate('http://example.com')->waitForNavigation();

$page->waitUntilContainsElement('div[data-name=\"el\"]');
```

If a string is passed to `Page::waitUntilContainsElement`, an instance of
`CSSSelector` is created for you by `Page::waitForElement`. To use other
selectors, you can pass an instance of the required `Selector`.

Wait for element by XPath selector:

```php
$page = $browser->createPage();
$page->navigate('http://example.com')->waitForNavigation();

$page->waitUntilContainsElement(new XPathSelector('//div[contains(text(), "content")]'));
```


You can send out a text to an element or click on it:

```php
Expand Down
28 changes: 24 additions & 4 deletions src/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
use HeadlessChromium\Cookies\CookiesCollection;
use HeadlessChromium\Dom\Dom;
use HeadlessChromium\Dom\Selector\CssSelector;
use HeadlessChromium\Dom\Selector\Selector;
use HeadlessChromium\Exception\CommunicationException;
use HeadlessChromium\Exception\EvaluationFailed;
use HeadlessChromium\Exception\InvalidTimezoneId;
use HeadlessChromium\Exception\JavascriptException;
use HeadlessChromium\Exception\NoResponseAvailable;
use HeadlessChromium\Exception\OperationTimedOut;
use HeadlessChromium\Exception\TargetDestroyed;
use HeadlessChromium\Input\Keyboard;
use HeadlessChromium\Input\Mouse;
Expand Down Expand Up @@ -457,9 +460,16 @@ private function waitForReloadGenerator($eventName, $loaderId)
/**
* Wait until page contains Node.
*
* @throws Exception\OperationTimedOut
* @param string|Selector $selectors
* @param int $timeout
*
* @throws CommunicationException
* @throws EvaluationFailed
* @throws OperationTimedOut
*
* @return Page
*/
public function waitUntilContainsElement(string $selectors, int $timeout = 30000): self
public function waitUntilContainsElement($selectors, int $timeout = 30000): self
{
$this->assertNotClosed();

Expand All @@ -469,18 +479,28 @@ public function waitUntilContainsElement(string $selectors, int $timeout = 30000
}

/**
* @param string|Selector $selectors
* @param int $position
*
* @throws CommunicationException
* @throws EvaluationFailed
*
* @return bool|\Generator
*
* @internal
*/
public function waitForElement(string $selectors, int $position = 1)
public function waitForElement($selectors, int $position = 1)
{
if (!($selectors instanceof Selector)) {
$selectors = new CssSelector($selectors);
}

$delay = 500;
$element = [];

while (true) {
try {
$element = Utils::getElementPositionFromPage($this, new CssSelector($selectors), $position);
$element = Utils::getElementPositionFromPage($this, $selectors, $position);
} catch (JavascriptException $exception) {
yield $delay;
}
Expand Down
26 changes: 24 additions & 2 deletions tests/PageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@

use finfo;
use HeadlessChromium\BrowserFactory;
use HeadlessChromium\Dom\Selector\XPathSelector;
use HeadlessChromium\Exception\InvalidTimezoneId;

/**
* @covers \HeadlessChromium\Page
*/
class PageTest extends BaseTestCase
{
private const WAIT_FOR_ELEMENT_HTML = '<div data-name="el">content</div>';
private const WAIT_FOR_ELEMENT_RESOURCE_FILE = 'elementLoad.html';

public function testSetViewport(): void
{
$factory = new BrowserFactory();
Expand Down Expand Up @@ -433,11 +437,29 @@ public function testWaitUntilContainsElement(): void
$browser = $factory->createBrowser();
$page = $browser->createPage();

$page->navigate(self::sitePath('elementLoad.html'))->waitForNavigation();
$page->navigate(self::sitePath(self::WAIT_FOR_ELEMENT_RESOURCE_FILE))->waitForNavigation();

self::assertStringNotContainsString(self::WAIT_FOR_ELEMENT_HTML, $page->getHtml());

$page->waitUntilContainsElement('div[data-name=\"el\"]');

self::assertStringContainsString('<div data-name="el"></div>', $page->getHtml());
self::assertStringContainsString(self::WAIT_FOR_ELEMENT_HTML, $page->getHtml());
}

public function testWaitUntilContainsElementByXPath(): void
{
$factory = new BrowserFactory();

$browser = $factory->createBrowser();
$page = $browser->createPage();

$page->navigate(self::sitePath(self::WAIT_FOR_ELEMENT_RESOURCE_FILE))->waitForNavigation();

self::assertStringNotContainsString(self::WAIT_FOR_ELEMENT_HTML, $page->getHtml());

$page->waitUntilContainsElement(new XPathSelector('//div[contains(text(), "content")]'));

self::assertStringContainsString(self::WAIT_FOR_ELEMENT_HTML, $page->getHtml());
}

public function testSetExtraHTTPHeaders(): void
Expand Down
1 change: 1 addition & 0 deletions tests/resources/static-web/elementLoad.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ <h1>page a</h1>
let el = document.createElement('div');

el.dataset.name = 'el';
el.innerHTML = 'content';

document.body.appendChild(el)
}, 500)
Expand Down

0 comments on commit d45e130

Please sign in to comment.