MouseApiTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /*
  3. * This file is part of Chrome PHP.
  4. *
  5. * (c) Soufiane Ghzal <sghzal@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace HeadlessChromium\Test;
  11. use HeadlessChromium\Browser;
  12. use HeadlessChromium\BrowserFactory;
  13. /**
  14. * @covers \HeadlessChromium\Browser
  15. * @covers \HeadlessChromium\Page
  16. */
  17. class MouseApiTest extends BaseTestCase
  18. {
  19. /**
  20. * @var Browser\ProcessAwareBrowser
  21. */
  22. public static $browser;
  23. public static function setUpBeforeClass(): void
  24. {
  25. parent::setUpBeforeClass();
  26. $factory = new BrowserFactory();
  27. self::$browser = $factory->createBrowser();
  28. }
  29. public static function tearDownAfterClass(): void
  30. {
  31. parent::tearDownAfterClass();
  32. self::$browser->close();
  33. }
  34. private function openSitePage($file)
  35. {
  36. $page = self::$browser->createPage();
  37. $page->navigate(self::sitePath($file))->waitForNavigation();
  38. return $page;
  39. }
  40. public function mouseFindProvider(): array
  41. {
  42. return [
  43. // position, expected page title
  44. [-1, 'c - test'],
  45. [2, 'b - test'],
  46. [99, 'a - test'],
  47. ];
  48. }
  49. /**
  50. * @throws \HeadlessChromium\Exception\CommunicationException
  51. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  52. */
  53. public function testClickLink(): void
  54. {
  55. // initial navigation
  56. $page = $this->openSitePage('b.html');
  57. $rect = $page
  58. ->evaluate('JSON.parse(JSON.stringify(document.querySelector("#a").getBoundingClientRect()));')
  59. ->getReturnValue();
  60. $page->mouse()->move($rect['x'], $rect['y'])->click();
  61. $page->waitForReload();
  62. $title = $page->evaluate('document.title')->getReturnValue();
  63. $this->assertEquals('a - test', $title);
  64. }
  65. /**
  66. * @throws \HeadlessChromium\Exception\CommunicationException
  67. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  68. */
  69. public function testScroll(): void
  70. {
  71. // initial navigation
  72. $page = $this->openSitePage('bigLayout.html');
  73. // scroll 100px down
  74. $page->mouse()->scrollDown(100);
  75. $windowScrollY = $page->evaluate('window.scrollY')->getReturnValue();
  76. $this->assertEquals(100, $windowScrollY);
  77. // scrolling 100px up should revert the last action
  78. $page->mouse()->scrollUp(100);
  79. $windowScrollY = $page->evaluate('window.scrollY')->getReturnValue();
  80. $this->assertEquals(0, $windowScrollY);
  81. }
  82. /**
  83. * @throws \HeadlessChromium\Exception\CommunicationException
  84. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  85. */
  86. public function testFind_withSingleElement(): void
  87. {
  88. // initial navigation
  89. $page = $this->openSitePage('b.html');
  90. $page->mouse()->find('#a')->click();
  91. $page->waitForReload();
  92. $title = $page->evaluate('document.title')->getReturnValue();
  93. $this->assertEquals('a - test', $title);
  94. }
  95. /**
  96. * @dataProvider mouseFindProvider
  97. *
  98. * @throws \HeadlessChromium\Exception\CommunicationException
  99. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  100. */
  101. public function testFind_withMultipleElements(int $position, string $expectedPageTitle): void
  102. {
  103. $page = $this->openSitePage('b.html');
  104. $page->mouse()->find('.a', $position)->click();
  105. $page->waitForReload();
  106. $title = $page->evaluate('document.title')->getReturnValue();
  107. $this->assertEquals($expectedPageTitle, $title);
  108. }
  109. /**
  110. * @throws \HeadlessChromium\Exception\CommunicationException
  111. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  112. */
  113. public function testFind_withScrolling(): void
  114. {
  115. // initial navigation
  116. $page = $this->openSitePage('bigLayout.html');
  117. $page->mouse()->find('#bottomLink');
  118. $page->mouse()->click();
  119. $page->waitForReload();
  120. $title = $page->evaluate('document.title')->getReturnValue();
  121. $this->assertEquals('a - test', $title);
  122. }
  123. /**
  124. * @throws \HeadlessChromium\Exception\CommunicationException
  125. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  126. * @throws \HeadlessChromium\Exception\ElementNotFoundException
  127. */
  128. public function testFind_withMissingElement(): void
  129. {
  130. $this->expectException(\HeadlessChromium\Exception\ElementNotFoundException::class);
  131. // initial navigation
  132. $page = $this->openSitePage('b.html');
  133. $page->mouse()->find('#missing');
  134. }
  135. /**
  136. * @throws \HeadlessChromium\Exception\CommunicationException
  137. * @throws \HeadlessChromium\Exception\NoResponseAvailable
  138. */
  139. public function testGetPosition(): void
  140. {
  141. // initial navigation
  142. $page = $this->openSitePage('b.html');
  143. $this->assertEquals(['x' => 0, 'y' => 0], $page->mouse()->getPosition());
  144. // find element with id "a"
  145. $page->mouse()->find('#a');
  146. $x = $page->mouse()->getPosition()['x'];
  147. $y = $page->mouse()->getPosition()['y'];
  148. $this->assertGreaterThanOrEqual(1, $x); // 8
  149. $this->assertLessThanOrEqual(51, $x);
  150. $this->assertGreaterThanOrEqual(1, $y); // 87
  151. $this->assertLessThanOrEqual(107, $y);
  152. }
  153. }