123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- <?php
- /*
- * This file is part of Chrome PHP.
- *
- * (c) Soufiane Ghzal <sghzal@gmail.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace HeadlessChromium\Test;
- use Generator;
- use HeadlessChromium\Browser;
- use HeadlessChromium\BrowserFactory;
- use HeadlessChromium\Dom\Selector\CssSelector;
- use HeadlessChromium\Dom\Selector\Selector;
- use HeadlessChromium\Dom\Selector\XPathSelector;
- /**
- * @covers \HeadlessChromium\Browser
- * @covers \HeadlessChromium\Page
- */
- class MouseApiTest extends BaseTestCase
- {
- /**
- * @var Browser\ProcessAwareBrowser
- */
- public static $browser;
- public static function setUpBeforeClass(): void
- {
- parent::setUpBeforeClass();
- $factory = new BrowserFactory();
- self::$browser = $factory->createBrowser();
- }
- public static function tearDownAfterClass(): void
- {
- parent::tearDownAfterClass();
- self::$browser->close();
- }
- private function openSitePage($file)
- {
- $page = self::$browser->createPage();
- $page->navigate(self::sitePath($file))->waitForNavigation();
- return $page;
- }
- /**
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testClickLink(): void
- {
- // initial navigation
- $page = $this->openSitePage('b.html');
- $rect = $page
- ->evaluate('JSON.parse(JSON.stringify(document.querySelector("#a").getBoundingClientRect()));')
- ->getReturnValue();
- $page->mouse()->move(\ceil($rect['x']), \ceil($rect['y']))->click();
- $page->waitForReload();
- $title = $page->evaluate('document.title')->getReturnValue();
- self::assertEquals('a - test', $title);
- }
- /**
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testScroll(): void
- {
- // initial navigation
- $page = $this->openSitePage('bigLayout.html');
- // scroll 100px down
- $page->mouse()->scrollDown(100);
- $windowScrollY = $page->evaluate('window.scrollY')->getReturnValue();
- self::assertEquals(100, $windowScrollY);
- self::assertEquals(100, $page->mouse()->getPosition()['y']);
- // scrolling 100px up should revert the last action
- $page->mouse()->scrollUp(100);
- $windowScrollY = $page->evaluate('window.scrollY')->getReturnValue();
- self::assertEquals(0, $windowScrollY);
- self::assertEquals(0, $page->mouse()->getPosition()['y']);
- // try to scroll more than possible
- $page->mouse()->scrollDown(10000);
- $windowScrollY = $page->evaluate('window.scrollY')->getReturnValue();
- self::assertLessThan(10000, $windowScrollY);
- self::assertLessThan(10000, $page->mouse()->getPosition()['y']);
- }
- /**
- * @dataProvider providerFindElement_withSingleElement
- *
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testFindElement_withSingleElement(Selector $selector): void
- {
- // initial navigation
- $page = $this->openSitePage('b.html');
- $page->mouse()->findElement($selector)->click();
- $page->waitForReload();
- $title = $page->evaluate('document.title')->getReturnValue();
- self::assertEquals('a - test', $title);
- }
- /**
- * @return Generator<string, array{Selector}>
- */
- public function providerFindElement_withSingleElement(): Generator
- {
- yield 'css' => [new CssSelector('#a')];
- yield 'xpath' => [new XPathSelector('//*[@id="a"]')];
- }
- /**
- * @dataProvider providerFindElement_afterMove
- *
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testFindElement_afterMove(Selector $selector): void
- {
- // initial navigation
- $page = $this->openSitePage('b.html');
- $page->mouse()->move(1000, 1000);
- $page->mouse()->findElement($selector)->click();
- $page->waitForReload();
- $title = $page->evaluate('document.title')->getReturnValue();
- self::assertEquals('a - test', $title);
- }
- /**
- * @return Generator<string, array{Selector}>
- */
- public function providerFindElement_afterMove(): Generator
- {
- yield 'css' => [new CssSelector('#a')];
- yield 'xpath' => [new XPathSelector('//*[@id="a"]')];
- }
- /**
- * @dataProvider providerFindElement_withMultipleElements
- *
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testFindElement_withMultipleElements(Selector $selector, int $position, string $expectedPageTitle): void
- {
- $page = $this->openSitePage('b.html');
- $page->mouse()->findElement($selector, $position)->click();
- $page->waitForReload();
- $title = $page->evaluate('document.title')->getReturnValue();
- self::assertEquals($expectedPageTitle, $title);
- }
- /**
- * @return Generator<array-key, array{Selector, int, string}>
- */
- public function providerFindElement_withMultipleElements(): Generator
- {
- $cssSelector = new CssSelector('.a');
- $xPathSelector = new XPathSelector('//*[@class="a"]');
- foreach (['css' => $cssSelector, 'xpath' => $xPathSelector] as $type => $selector) {
- yield $type.' – 1' => [$selector, -1, 'c - test'];
- yield $type.' – 2' => [$selector, 2, 'b - test'];
- yield $type.' – 3' => [$selector, 99, 'a - test'];
- }
- }
- /**
- * @dataProvider providerFindElement_withScrolling
- *
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testFindElement_withScrolling(Selector $selector): void
- {
- // initial navigation
- $page = $this->openSitePage('bigLayout.html');
- $page->mouse()->findElement($selector);
- $page->mouse()->click();
- $page->waitForReload();
- $title = $page->evaluate('document.title')->getReturnValue();
- self::assertEquals('a - test', $title);
- }
- /**
- * @return Generator<string, array{Selector}>
- */
- public function providerFindElement_withScrolling(): Generator
- {
- yield 'css' => [new CssSelector('#bottomLink')];
- yield 'xpath' => [new XPathSelector('//*[@id="bottomLink"]')];
- }
- /**
- * @dataProvider providerFindElement_withMissingElement
- *
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- * @throws \HeadlessChromium\Exception\ElementNotFoundException
- */
- public function testFindElement_withMissingElement(Selector $selector): void
- {
- $this->expectException(\HeadlessChromium\Exception\ElementNotFoundException::class);
- // initial navigation
- $page = $this->openSitePage('b.html');
- $page->mouse()->findElement($selector);
- }
- /**
- * @return Generator<string, array{Selector}>
- */
- public function providerFindElement_withMissingElement(): Generator
- {
- yield 'css' => [new CssSelector('#missing')];
- yield 'xpath' => [new XPathSelector('//*[@id="missing"]')];
- }
- /**
- * @throws \HeadlessChromium\Exception\CommunicationException
- * @throws \HeadlessChromium\Exception\NoResponseAvailable
- */
- public function testGetPosition(): void
- {
- // initial navigation
- $page = $this->openSitePage('b.html');
- self::assertEquals(['x' => 0, 'y' => 0], $page->mouse()->getPosition());
- // find element with id "a"
- $page->mouse()->find('#a');
- $x = $page->mouse()->getPosition()['x'];
- $y = $page->mouse()->getPosition()['y'];
- self::assertGreaterThanOrEqual(1, $x); // 8
- self::assertLessThanOrEqual(51, $x);
- self::assertGreaterThanOrEqual(1, $y); // 87
- self::assertLessThanOrEqual(107, $y);
- }
- }
|