PageTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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 finfo;
  12. use HeadlessChromium\BrowserFactory;
  13. use HeadlessChromium\Exception\InvalidTimezoneId;
  14. /**
  15. * @covers \HeadlessChromium\Page
  16. */
  17. class PageTest extends BaseTestCase
  18. {
  19. public function testSetViewport(): void
  20. {
  21. $factory = new BrowserFactory();
  22. $browser = $factory->createBrowser([
  23. 'windowSize' => [500, 500],
  24. ]);
  25. $page = $browser->createPage();
  26. $page->setViewport(100, 300)->await();
  27. $response = $page->evaluate('[window.innerWidth, window.innerHeight]')->getReturnValue();
  28. $this->assertEquals([100, 300], $response);
  29. }
  30. public function testSetUserAgent(): void
  31. {
  32. $factory = new BrowserFactory();
  33. $browser = $factory->createBrowser();
  34. $pageFooBar = $browser->createPage();
  35. $pageBarBaz = $browser->createPage();
  36. $pageFooBar->setUserAgent('foobar')->await();
  37. $pageBarBaz->setUserAgent('barbaz')->await();
  38. $pageFooBar->navigate(self::sitePath('a.html'))->waitForNavigation();
  39. $pageBarBaz->navigate(self::sitePath('a.html'))->waitForNavigation();
  40. $value1 = $pageFooBar->evaluate('navigator.userAgent')->getReturnValue();
  41. $value2 = $pageBarBaz->evaluate('navigator.userAgent')->getReturnValue();
  42. $this->assertEquals('foobar', $value1);
  43. $this->assertEquals('barbaz', $value2);
  44. }
  45. public function testSetTimezone(): void
  46. {
  47. $factory = new BrowserFactory();
  48. $browser = $factory->createBrowser();
  49. $page = $browser->createPage();
  50. $page->evaluate('
  51. globalThis.date = new Date(1479579154987);
  52. ');
  53. $page->setTimezone('America/Jamaica');
  54. $this->assertEquals(
  55. 'Sat Nov 19 2016 13:12:34 GMT-0500 (Eastern Standard Time)',
  56. $page->evaluate('date.toString()')->getReturnValue()
  57. );
  58. $page->setTimezone('Pacific/Honolulu');
  59. $this->assertEquals(
  60. 'Sat Nov 19 2016 08:12:34 GMT-1000 (Hawaii-Aleutian Standard Time)',
  61. $page->evaluate('date.toString()')->getReturnValue()
  62. );
  63. $page->setTimezone('America/Buenos_Aires');
  64. $this->assertEquals(
  65. 'Sat Nov 19 2016 15:12:34 GMT-0300 (Argentina Standard Time)',
  66. $page->evaluate('date.toString()')->getReturnValue()
  67. );
  68. $page->setTimezone('Europe/Berlin');
  69. $this->assertEquals(
  70. 'Sat Nov 19 2016 19:12:34 GMT+0100 (Central European Standard Time)',
  71. $page->evaluate('date.toString()')->getReturnValue()
  72. );
  73. $page->setTimezone('Europe/Berlin');
  74. $this->assertEquals(
  75. 'Sat Nov 19 2016 19:12:34 GMT+0100 (Central European Standard Time)',
  76. $page->evaluate('date.toString()')->getReturnValue()
  77. );
  78. $page->setTimezone('gteged');
  79. }
  80. public function testSetTimezoneInvalid(): void
  81. {
  82. $this->expectException(InvalidTimezoneId::class);
  83. $factory = new BrowserFactory();
  84. $browser = $factory->createBrowser();
  85. $page = $browser->createPage();
  86. $page->setTimezone('Foo/Bar');
  87. $this->expectExceptionMessage('Invalid Timezone ID: Foo/Bar');
  88. $page->setTimezone('Baz/Qux');
  89. $this->expectExceptionMessage('Invalid Timezone ID: Baz/Qux');
  90. }
  91. public function testPreScriptOption(): void
  92. {
  93. $factory = new BrowserFactory();
  94. $browser = $factory->createBrowser();
  95. $preScript1 =
  96. "if(!('foo' in navigator)) {
  97. navigator.foo = 0
  98. }
  99. navigator.foo++;";
  100. $preScript2 =
  101. "if(!('bar' in navigator)) {
  102. navigator.bar = 10
  103. }
  104. navigator.bar++;";
  105. $page = $browser->createPage();
  106. $page2 = $browser->createPage();
  107. $page->addPreScript($preScript1);
  108. $page->addPreScript($preScript2);
  109. // make sure prescript evaluates
  110. $page->navigate(self::sitePath('a.html'))->waitForNavigation();
  111. $fooValue = $page->evaluate('navigator.foo')->getReturnValue();
  112. $barValue = $page->evaluate('navigator.bar')->getReturnValue();
  113. $this->assertEquals(1, $fooValue);
  114. $this->assertEquals(11, $barValue);
  115. // make sure prescript is not adding again and again on every requests
  116. $page->navigate(self::sitePath('b.html'))->waitForNavigation();
  117. $fooValue = $page->evaluate('navigator.foo')->getReturnValue();
  118. $barValue = $page->evaluate('navigator.bar')->getReturnValue();
  119. $this->assertEquals(1, $fooValue);
  120. $this->assertEquals(11, $barValue);
  121. // make sure prescript did not pollute other pages
  122. $page2->navigate(self::sitePath('b.html'))->waitForNavigation();
  123. $fooValue = $page2->evaluate('navigator.foo')->getReturnValue();
  124. $barValue = $page2->evaluate('navigator.bar')->getReturnValue();
  125. $this->assertEquals(null, $fooValue);
  126. $this->assertEquals(null, $barValue);
  127. }
  128. public function testCallFunction(): void
  129. {
  130. $factory = new BrowserFactory();
  131. $browser = $factory->createBrowser();
  132. $page = $browser->createPage();
  133. $evaluation = $page->callFunction('function(a, b) { window.foo = a + b; return window.foo;}', [1, 2]);
  134. $this->assertEquals(3, $evaluation->getReturnValue());
  135. $this->assertEquals(3, $page->evaluate('window.foo')->getReturnValue());
  136. }
  137. public function testCallFunctionPromise(): void
  138. {
  139. $factory = new BrowserFactory();
  140. $browser = $factory->createBrowser();
  141. $page = $browser->createPage();
  142. $evaluation = $page->callFunction('function(a, b) {
  143. return new Promise(resolve => {
  144. setTimeout(() => {
  145. resolve(a + b);
  146. }, 100);
  147. })
  148. }', [1, 2]);
  149. $this->assertEquals(3, $evaluation->getReturnValue());
  150. }
  151. public function testEvaluatePromise(): void
  152. {
  153. $factory = new BrowserFactory();
  154. $browser = $factory->createBrowser();
  155. $page = $browser->createPage();
  156. $evaluation = $page->evaluate('new Promise(resolve => {
  157. setTimeout(() => {
  158. resolve(11);
  159. }, 100);
  160. })');
  161. $this->assertEquals(11, $evaluation->getReturnValue());
  162. }
  163. public function testAddScriptTagContent(): void
  164. {
  165. $factory = new BrowserFactory();
  166. $browser = $factory->createBrowser();
  167. $page = $browser->createPage();
  168. $page->addScriptTag([
  169. 'content' => 'window.foo = "bar";',
  170. ])->waitForResponse();
  171. $this->assertEquals('bar', $page->evaluate('window.foo')->getReturnValue());
  172. }
  173. public function testAddScriptTagUrl(): void
  174. {
  175. $factory = new BrowserFactory();
  176. $browser = $factory->createBrowser();
  177. $page = $browser->createPage();
  178. $page->navigate(
  179. self::sitePath('a.html')
  180. )->waitForNavigation();
  181. $page->addScriptTag([
  182. 'url' => self::sitePath('jsInclude.js'),
  183. ])->waitForResponse();
  184. $isIncluded = $page->evaluate('window.testJsIsIncluded')->getReturnValue();
  185. $scriptSrc = $page->evaluate('document.querySelector("script").getAttribute("src")')->getReturnValue();
  186. $this->assertEquals('isIncluded', $isIncluded);
  187. $this->assertStringStartsWith('file://', $scriptSrc);
  188. $this->assertStringEndsWith('/jsInclude.js', $scriptSrc);
  189. }
  190. public function testGetLayoutMetrics(): void
  191. {
  192. $factory = new BrowserFactory();
  193. $browser = $factory->createBrowser([
  194. 'windowSize' => [500, 500],
  195. ]);
  196. $page = $browser->createPage();
  197. $page->navigate(self::sitePath('bigLayout.html'))->waitForNavigation();
  198. $page->setViewport(100, 300)->await();
  199. $metrics = $page->getLayoutMetrics();
  200. $contentSize = $metrics->getContentSize();
  201. $layoutViewport = $metrics->getLayoutViewport();
  202. $visualViewport = $metrics->getVisualViewport();
  203. $this->assertEquals(
  204. [
  205. 'x' => 0,
  206. 'y' => 0,
  207. 'width' => 900,
  208. 'height' => 1000,
  209. ],
  210. $contentSize
  211. );
  212. $this->assertEquals(
  213. [
  214. 'pageX' => 0,
  215. 'pageY' => 0,
  216. 'clientWidth' => 100,
  217. 'clientHeight' => 300,
  218. ],
  219. $layoutViewport
  220. );
  221. $this->assertEquals(
  222. [
  223. 'offsetX' => 0,
  224. 'offsetY' => 0,
  225. 'pageX' => 0,
  226. 'pageY' => 0,
  227. 'clientWidth' => 100,
  228. 'clientHeight' => 300,
  229. 'scale' => 1,
  230. 'zoom' => 1,
  231. ],
  232. $visualViewport
  233. );
  234. }
  235. public function testGetFullPageClip(): void
  236. {
  237. $factory = new BrowserFactory();
  238. $browser = $factory->createBrowser([
  239. 'windowSize' => [500, 500],
  240. ]);
  241. $page = $browser->createPage();
  242. $page->navigate(self::sitePath('bigLayout.html'))->waitForNavigation();
  243. $clip = $page->getFullPageClip();
  244. $this->assertEquals(0, $clip->getX());
  245. $this->assertEquals(0, $clip->getY());
  246. $this->assertEquals(900, $clip->getWidth());
  247. $this->assertEquals(1000, $clip->getHeight());
  248. }
  249. public function testPdf(): void
  250. {
  251. $finfo = new finfo(\FILEINFO_MIME_TYPE);
  252. $factory = new BrowserFactory();
  253. $browser = $factory->createBrowser();
  254. $page = $browser->createPage();
  255. $page->navigate(self::sitePath('index.html'))->waitForNavigation();
  256. $pagePdf = $page->pdf(['landscape' => false]);
  257. $pdf = $pagePdf->getBase64();
  258. $mimeType = $finfo->buffer(\base64_decode($pdf));
  259. $this->assertSame('application/pdf', $mimeType);
  260. }
  261. public function testGetHtml(): void
  262. {
  263. $factory = new BrowserFactory();
  264. $browser = $factory->createBrowser();
  265. $page = $browser->createPage();
  266. $page->navigate(self::sitePath('index.html'))->waitForNavigation();
  267. $this->assertStringContainsString('<h1>bar</h1>', $page->getHtml());
  268. }
  269. }