PhpBrowserTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. <?php
  2. use Codeception\Util\Stub;
  3. require_once 'tests/data/app/data.php';
  4. require_once __DIR__ . '/TestsForBrowsers.php';
  5. use GuzzleHttp\Psr7\Response;
  6. class PhpBrowserTest extends TestsForBrowsers
  7. {
  8. /**
  9. * @var \Codeception\Module\PhpBrowser
  10. */
  11. protected $module;
  12. protected $history = [];
  13. protected function setUp()
  14. {
  15. $this->module = new \Codeception\Module\PhpBrowser(make_container());
  16. $url = 'http://localhost:8000';
  17. $this->module->_setConfig(array('url' => $url));
  18. $this->module->_initialize();
  19. $this->module->_before($this->makeTest());
  20. if (class_exists('GuzzleHttp\Url')) {
  21. $this->history = new \GuzzleHttp\Subscriber\History();
  22. $this->module->guzzle->getEmitter()->attach($this->history);
  23. } else {
  24. $this->module->guzzle->getConfig('handler')->push(\GuzzleHttp\Middleware::history($this->history));
  25. }
  26. }
  27. private function getLastRequest()
  28. {
  29. if (is_array($this->history)) {
  30. return end($this->history)['request'];
  31. }
  32. return $this->history->getLastRequest();
  33. }
  34. protected function tearDown()
  35. {
  36. if ($this->module) {
  37. $this->module->_after($this->makeTest());
  38. }
  39. data::clean();
  40. }
  41. protected function makeTest()
  42. {
  43. return Stub::makeEmpty('\Codeception\Test\Cept');
  44. }
  45. public function testAjax()
  46. {
  47. $this->module->amOnPage('/');
  48. $this->module->sendAjaxGetRequest('/info');
  49. $this->assertNotNull(data::get('ajax'));
  50. $this->module->sendAjaxPostRequest('/form/complex', array('show' => 'author'));
  51. $this->assertNotNull(data::get('ajax'));
  52. $post = data::get('form');
  53. $this->assertEquals('author', $post['show']);
  54. }
  55. public function testLinksWithNonLatin()
  56. {
  57. $this->module->amOnPage('/info');
  58. $this->module->seeLink('Ссылочка');
  59. $this->module->click('Ссылочка');
  60. }
  61. /**
  62. * @see https://github.com/Codeception/Codeception/issues/4509
  63. */
  64. public function testSeeTextAfterJSComparisionOperator()
  65. {
  66. $this->module->amOnPage('/info');
  67. $this->module->see('Text behind JS comparision');
  68. }
  69. public function testSetMultipleCookies()
  70. {
  71. $this->module->amOnPage('/');
  72. $cookie_name_1 = 'test_cookie';
  73. $cookie_value_1 = 'this is a test';
  74. $this->module->setCookie($cookie_name_1, $cookie_value_1);
  75. $cookie_name_2 = '2_test_cookie';
  76. $cookie_value_2 = '2 this is a test';
  77. $this->module->setCookie($cookie_name_2, $cookie_value_2);
  78. $this->module->seeCookie($cookie_name_1);
  79. $this->module->seeCookie($cookie_name_2);
  80. $this->module->dontSeeCookie('evil_cookie');
  81. $cookie1 = $this->module->grabCookie($cookie_name_1);
  82. $this->assertEquals($cookie_value_1, $cookie1);
  83. $cookie2 = $this->module->grabCookie($cookie_name_2);
  84. $this->assertEquals($cookie_value_2, $cookie2);
  85. $this->module->resetCookie($cookie_name_1);
  86. $this->module->dontSeeCookie($cookie_name_1);
  87. $this->module->seeCookie($cookie_name_2);
  88. $this->module->resetCookie($cookie_name_2);
  89. $this->module->dontSeeCookie($cookie_name_2);
  90. }
  91. public function testSessionsHaveIndependentCookies()
  92. {
  93. $this->module->amOnPage('/');
  94. $cookie_name_1 = 'test_cookie';
  95. $cookie_value_1 = 'this is a test';
  96. $this->module->setCookie($cookie_name_1, $cookie_value_1);
  97. $session = $this->module->_backupSession();
  98. $this->module->_initializeSession();
  99. $this->module->dontSeeCookie($cookie_name_1);
  100. $cookie_name_2 = '2_test_cookie';
  101. $cookie_value_2 = '2 this is a test';
  102. $this->module->setCookie($cookie_name_2, $cookie_value_2);
  103. $this->module->_loadSession($session);
  104. $this->module->dontSeeCookie($cookie_name_2);
  105. $this->module->seeCookie($cookie_name_1);
  106. }
  107. public function testSubmitFormGet()
  108. {
  109. $I = $this->module;
  110. $I->amOnPage('/search');
  111. $I->submitForm('form', array('searchQuery' => 'test'));
  112. $I->see('Success');
  113. }
  114. public function testHtmlRedirect()
  115. {
  116. $this->module->amOnPage('/redirect2');
  117. $this->module->seeResponseCodeIs(200);
  118. $this->module->seeCurrentUrlEquals('/info');
  119. $this->module->amOnPage('/redirect_interval');
  120. $this->module->seeCurrentUrlEquals('/redirect_interval');
  121. }
  122. public function testHtmlRedirectWithParams()
  123. {
  124. $this->module->amOnPage('/redirect_params');
  125. $this->module->seeResponseCodeIs(200);
  126. $this->module->seeCurrentUrlEquals('/search?one=1&two=2');
  127. }
  128. public function testMetaRefresh()
  129. {
  130. $this->module->amOnPage('/redirect_meta_refresh');
  131. $this->module->seeResponseCodeIs(200);
  132. $this->module->seeCurrentUrlEquals('/info');
  133. }
  134. public function testMetaRefreshIsIgnoredIfIntervalIsLongerThanMaxInterval()
  135. {
  136. // prepare config
  137. $config = $this->module->_getConfig();
  138. $config['refresh_max_interval'] = 3; // less than 9
  139. $this->module->_reconfigure($config);
  140. $this->module->amOnPage('/redirect_meta_refresh');
  141. $this->module->seeResponseCodeIs(200);
  142. $this->module->seeCurrentUrlEquals('/redirect_meta_refresh');
  143. }
  144. public function testRefreshRedirect()
  145. {
  146. $this->module->amOnPage('/redirect3');
  147. $this->module->seeResponseCodeIs(200);
  148. $this->module->seeCurrentUrlEquals('/info');
  149. $this->module->amOnPage('/redirect_header_interval');
  150. $this->module->seeCurrentUrlEquals('/redirect_header_interval');
  151. $this->module->see('Welcome to test app!');
  152. }
  153. public function testRedirectWithGetParams()
  154. {
  155. $this->module->amOnPage('/redirect4');
  156. $this->module->seeInCurrentUrl('/search?ln=test@gmail.com&sn=testnumber');
  157. $params = data::get('params');
  158. $this->assertContains('test@gmail.com', $params);
  159. }
  160. public function testRedirectBaseUriHasPath()
  161. {
  162. // prepare config
  163. $config = $this->module->_getConfig();
  164. $config['url'] .= '/somepath'; // append path to the base url
  165. $this->module->_reconfigure($config);
  166. $this->module->amOnPage('/redirect_base_uri_has_path');
  167. $this->module->seeResponseCodeIs(200);
  168. $this->module->seeCurrentUrlEquals('/somepath/info');
  169. $this->module->see('Lots of valuable data here');
  170. }
  171. public function testRedirectBaseUriHasPathAnd302Code()
  172. {
  173. // prepare config
  174. $config = $this->module->_getConfig();
  175. $config['url'] .= '/somepath'; // append path to the base url
  176. $this->module->_reconfigure($config);
  177. $this->module->amOnPage('/redirect_base_uri_has_path_302');
  178. $this->module->seeResponseCodeIs(200);
  179. $this->module->seeCurrentUrlEquals('/somepath/info');
  180. $this->module->see('Lots of valuable data here');
  181. }
  182. public function testRelativeRedirect()
  183. {
  184. // test relative redirects where the effective request URI is in a
  185. // subdirectory
  186. $this->module->amOnPage('/relative/redirect');
  187. $this->module->seeResponseCodeIs(200);
  188. $this->module->seeCurrentUrlEquals('/relative/info');
  189. // also, test relative redirects where the effective request URI is not
  190. // in a subdirectory
  191. $this->module->amOnPage('/relative_redirect');
  192. $this->module->seeResponseCodeIs(200);
  193. $this->module->seeCurrentUrlEquals('/info');
  194. }
  195. public function testChainedRedirects()
  196. {
  197. $this->module->amOnPage('/redirect_twice');
  198. $this->module->seeResponseCodeIs(200);
  199. $this->module->seeCurrentUrlEquals('/info');
  200. }
  201. public function testDisabledRedirects()
  202. {
  203. $this->module->client->followRedirects(false);
  204. $this->module->amOnPage('/redirect_twice');
  205. $this->module->seeResponseCodeIs(302);
  206. $this->module->seeCurrentUrlEquals('/redirect_twice');
  207. }
  208. public function testRedirectLimitReached()
  209. {
  210. $this->module->client->setMaxRedirects(1);
  211. try {
  212. $this->module->amOnPage('/redirect_twice');
  213. $this->assertTrue(false, 'redirect limit is not respected');
  214. } catch (\LogicException $e) {
  215. $this->assertEquals(
  216. 'The maximum number (1) of redirections was reached.',
  217. $e->getMessage(),
  218. 'redirect limit is respected'
  219. );
  220. }
  221. }
  222. public function testRedirectLimitNotReached()
  223. {
  224. $this->module->client->setMaxRedirects(2);
  225. $this->module->amOnPage('/redirect_twice');
  226. $this->module->seeResponseCodeIs(200);
  227. $this->module->seeCurrentUrlEquals('/info');
  228. }
  229. public function testLocationHeaderDoesNotRedirectWhenStatusCodeIs201()
  230. {
  231. $this->module->amOnPage('/location_201');
  232. $this->module->seeResponseCodeIs(201);
  233. $this->module->seeCurrentUrlEquals('/location_201');
  234. }
  235. public function testRedirectToAnotherDomainUsingSchemalessUrl()
  236. {
  237. $this->module->amOnUrl('http://httpbin.org/redirect-to?url=//example.org/');
  238. $currentUrl = $this->module->client->getHistory()->current()->getUri();
  239. $this->assertSame('http://example.org/', $currentUrl);
  240. }
  241. public function testSetCookieByHeader()
  242. {
  243. $this->module->amOnPage('/cookies2');
  244. $this->module->seeResponseCodeIs(200);
  245. $this->module->seeCookie('a');
  246. $this->assertEquals('b', $this->module->grabCookie('a'));
  247. $this->module->seeCookie('c');
  248. }
  249. public function testSettingContentTypeFromHtml()
  250. {
  251. $this->module->amOnPage('/content-iso');
  252. $charset = $this->module->client->getResponse()->getHeader('Content-Type');
  253. $this->assertEquals('text/html;charset=ISO-8859-1', $charset);
  254. }
  255. public function testSettingCharsetFromHtml()
  256. {
  257. $this->module->amOnPage('/content-cp1251');
  258. $charset = $this->module->client->getResponse()->getHeader('Content-Type');
  259. $this->assertEquals('text/html;charset=windows-1251', $charset);
  260. }
  261. /**
  262. * @Issue https://github.com/Codeception/Codeception/issues/933
  263. */
  264. public function testSubmitFormWithQueries()
  265. {
  266. $this->module->amOnPage('/form/example3');
  267. $this->module->seeElement('form');
  268. $this->module->submitForm('form', array(
  269. 'name' => 'jon',
  270. ));
  271. $form = data::get('form');
  272. $this->assertEquals('jon', $form['name']);
  273. $this->module->seeCurrentUrlEquals('/form/example3?validate=yes');
  274. }
  275. public function testHeadersBySetHeader()
  276. {
  277. $this->module->setHeader('xxx', 'yyyy');
  278. $this->module->amOnPage('/');
  279. $this->assertTrue($this->getLastRequest()->hasHeader('xxx'));
  280. }
  281. public function testDeleteHeaders()
  282. {
  283. $this->module->setHeader('xxx', 'yyyy');
  284. $this->module->deleteHeader('xxx');
  285. $this->module->amOnPage('/');
  286. $this->assertFalse($this->getLastRequest()->hasHeader('xxx'));
  287. }
  288. public function testDeleteHeadersByEmptyValue()
  289. {
  290. $this->module->setHeader('xxx', 'yyyy');
  291. $this->module->setHeader('xxx', '');
  292. $this->module->amOnPage('/');
  293. $this->assertFalse($this->getLastRequest()->hasHeader('xxx'));
  294. }
  295. public function testCurlOptions()
  296. {
  297. $this->module->_setConfig(array('url' => 'http://google.com', 'curl' => array('CURLOPT_NOBODY' => true)));
  298. $this->module->_initialize();
  299. if (method_exists($this->module->guzzle, 'getConfig')) {
  300. $config = $this->module->guzzle->getConfig();
  301. } else {
  302. $config = $this->module->guzzle->getDefaultOption('config');
  303. }
  304. $this->assertArrayHasKey('curl', $config);
  305. $this->assertArrayHasKey(CURLOPT_NOBODY, $config['curl']);
  306. }
  307. public function testCurlSslOptions()
  308. {
  309. if (getenv('WERCKER_ROOT')) {
  310. $this->markTestSkipped('Disabled on Wercker CI');
  311. }
  312. $this->module->_setConfig(array(
  313. 'url' => 'https://google.com',
  314. 'curl' => array(
  315. 'CURLOPT_NOBODY' => true,
  316. 'CURLOPT_SSL_CIPHER_LIST' => 'TLSv1',
  317. )));
  318. $this->module->_initialize();
  319. if (method_exists($this->module->guzzle, 'getConfig')) {
  320. $config = $this->module->guzzle->getConfig();
  321. } else {
  322. $config = $this->module->guzzle->getDefaultOption('config');
  323. }
  324. $this->assertArrayHasKey('curl', $config);
  325. $this->assertArrayHasKey(CURLOPT_SSL_CIPHER_LIST, $config['curl']);
  326. $this->module->amOnPage('/');
  327. $this->assertSame('', $this->module->_getResponseContent(), 'CURLOPT_NOBODY setting is not respected');
  328. }
  329. public function testHttpAuth()
  330. {
  331. $this->module->amOnPage('/auth');
  332. $this->module->seeResponseCodeIs(401);
  333. $this->module->see('Unauthorized');
  334. $this->module->amHttpAuthenticated('davert', 'password');
  335. $this->module->amOnPage('/auth');
  336. $this->module->seeResponseCodeIs(200);
  337. $this->module->dontSee('Unauthorized');
  338. $this->module->see("Welcome, davert");
  339. $this->module->amHttpAuthenticated(null, null);
  340. $this->module->amOnPage('/auth');
  341. $this->module->seeResponseCodeIs(401);
  342. $this->module->amHttpAuthenticated('davert', '123456');
  343. $this->module->amOnPage('/auth');
  344. $this->module->see('Forbidden');
  345. }
  346. public function testRawGuzzle()
  347. {
  348. $code = $this->module->executeInGuzzle(function (\GuzzleHttp\Client $client) {
  349. $res = $client->get('/info');
  350. return $res->getStatusCode();
  351. });
  352. $this->assertEquals(200, $code);
  353. }
  354. /**
  355. * If we have a form with fields like
  356. * ```
  357. * <input type="file" name="foo" />
  358. * <input type="file" name="foo[bar]" />
  359. * ```
  360. * then only array variable will be used while simple variable will be ignored in php $_FILES
  361. * (eg $_FILES = [
  362. * foo => [
  363. * tmp_name => [
  364. * 'bar' => 'asdf'
  365. * ],
  366. * //...
  367. * ]
  368. * ]
  369. * )
  370. * (notice there is no entry for file "foo", only for file "foo[bar]"
  371. * this will check if current element contains inner arrays within it's keys
  372. * so we can ignore element itself and only process inner files
  373. */
  374. public function testFormWithFilesInOnlyArray()
  375. {
  376. $this->shouldFail();
  377. $this->module->amOnPage('/form/example13');
  378. $this->module->attachFile('foo', 'app/avatar.jpg');
  379. $this->module->attachFile('foo[bar]', 'app/avatar.jpg');
  380. $this->module->click('Submit');
  381. }
  382. public function testDoubleSlash()
  383. {
  384. $I = $this->module;
  385. $I->amOnPage('/register');
  386. $I->submitForm('form', array('test' => 'test'));
  387. $formUrl = $this->module->client->getHistory()->current()->getUri();
  388. $formPath = parse_url($formUrl)['path'];
  389. $this->assertEquals($formPath, '/register');
  390. }
  391. public function testFillFieldWithoutPage()
  392. {
  393. $this->setExpectedException("\\Codeception\\Exception\\ModuleException");
  394. $this->module->fillField('#name', 'Nothing special');
  395. }
  396. public function testArrayFieldSubmitForm()
  397. {
  398. $this->skipForOldGuzzle();
  399. $this->module->amOnPage('/form/example17');
  400. $this->module->submitForm(
  401. 'form',
  402. [
  403. 'FooBar' => ['bar' => 'booze'],
  404. 'Food' => [
  405. 'beer' => [
  406. 'yum' => ['yeah' => 'crunked']
  407. ]
  408. ]
  409. ]
  410. );
  411. $data = data::get('form');
  412. $this->assertEquals('booze', $data['FooBar']['bar']);
  413. $this->assertEquals('crunked', $data['Food']['beer']['yum']['yeah']);
  414. }
  415. public function testCookiesForDomain()
  416. {
  417. $this->skipForOldGuzzle();
  418. $mock = new \GuzzleHttp\Handler\MockHandler([
  419. new Response(200, ['X-Foo' => 'Bar']),
  420. ]);
  421. $handler = \GuzzleHttp\HandlerStack::create($mock);
  422. $handler->push(\GuzzleHttp\Middleware::history($this->history));
  423. $client = new \GuzzleHttp\Client(['handler' => $handler, 'base_uri' => 'http://codeception.com']);
  424. $guzzleConnector = new \Codeception\Lib\Connector\Guzzle6();
  425. $guzzleConnector->setClient($client);
  426. $guzzleConnector->getCookieJar()->set(new \Symfony\Component\BrowserKit\Cookie('hello', 'world'));
  427. $guzzleConnector->request('GET', 'http://codeception.com/');
  428. $this->assertArrayHasKey('cookies', $this->history[0]['options']);
  429. /** @var $cookie GuzzleHttp\Cookie\SetCookie **/
  430. $cookies = $this->history[0]['options']['cookies']->toArray();
  431. $cookie = reset($cookies);
  432. $this->assertEquals('codeception.com', $cookie['Domain']);
  433. }
  434. /**
  435. * @issue https://github.com/Codeception/Codeception/issues/2653
  436. */
  437. public function testSetCookiesByOptions()
  438. {
  439. $config = $this->module->_getConfig();
  440. $config['cookies'] = [
  441. [
  442. 'Name' => 'foo',
  443. 'Value' => 'bar1',
  444. ],
  445. [
  446. 'Name' => 'baz',
  447. 'Value' => 'bar2',
  448. ],
  449. ];
  450. $this->module->_reconfigure($config);
  451. // this url redirects if cookies are present
  452. $this->module->amOnPage('/cookies');
  453. $this->module->seeCurrentUrlEquals('/info');
  454. }
  455. private function skipForOldGuzzle()
  456. {
  457. if (class_exists('GuzzleHttp\Url')) {
  458. $this->markTestSkipped("Not for Guzzle <6");
  459. }
  460. }
  461. /**
  462. * @issue https://github.com/Codeception/Codeception/issues/2234
  463. */
  464. public function testEmptyValueOfCookie()
  465. {
  466. //set cookie
  467. $this->module->amOnPage('/cookies2');
  468. $this->module->amOnPage('/unset-cookie');
  469. $this->module->seeResponseCodeIs(200);
  470. $this->module->dontSeeCookie('a');
  471. }
  472. public function testRequestApi()
  473. {
  474. $this->setExpectedException('Codeception\Exception\ModuleException');
  475. $response = $this->module->_request('POST', '/form/try', ['user' => 'davert']);
  476. $data = data::get('form');
  477. $this->assertEquals('davert', $data['user']);
  478. $this->assertInternalType('string', $response);
  479. $this->assertContains('Welcome to test app', $response);
  480. $this->module->click('Welcome to test app'); // page not loaded
  481. }
  482. public function testLoadPageApi()
  483. {
  484. $this->module->_loadPage('POST', '/form/try', ['user' => 'davert']);
  485. $data = data::get('form');
  486. $this->assertEquals('davert', $data['user']);
  487. $this->module->see('Welcome to test app');
  488. $this->module->click('More info');
  489. $this->module->seeInCurrentUrl('/info');
  490. }
  491. /**
  492. * @issue https://github.com/Codeception/Codeception/issues/2408
  493. */
  494. public function testClickFailure()
  495. {
  496. $this->module->amOnPage('/info');
  497. $this->setExpectedException(
  498. 'Codeception\Exception\ElementNotFound',
  499. "'Sign In!' is invalid CSS and XPath selector and Link or Button element with 'name=Sign In!' was not found"
  500. );
  501. $this->module->click('Sign In!');
  502. }
  503. /**
  504. * @issue https://github.com/Codeception/Codeception/issues/2841
  505. */
  506. public function testSubmitFormDoesNotKeepGetParameters()
  507. {
  508. $this->module->amOnPage('/form/bug2841?stuff=other');
  509. $this->module->fillField('#texty', 'thingshjere');
  510. $this->module->click('#submit-registration');
  511. $this->assertEmpty(data::get('query'), 'Query string is not empty');
  512. }
  513. public function testClickLinkAndFillField()
  514. {
  515. $this->module->amOnPage('/info');
  516. $this->module->click('Sign in!');
  517. $this->module->seeCurrentUrlEquals('/login');
  518. $this->module->fillField('email', 'email@example.org');
  519. }
  520. public function testClickSelectsClickableElementFromMatches()
  521. {
  522. $this->module->amOnPage('/form/multiple_matches');
  523. $this->module->click('Press Me!');
  524. $this->module->seeCurrentUrlEquals('/info');
  525. }
  526. public function testClickSelectsClickableElementFromMatchesUsingCssLocator()
  527. {
  528. $this->module->amOnPage('/form/multiple_matches');
  529. $this->module->click(['css' => '.link']);
  530. $this->module->seeCurrentUrlEquals('/info');
  531. }
  532. /**
  533. * @expectedException PHPUnit\Framework\AssertionFailedError
  534. */
  535. public function testClickingOnButtonOutsideFormDoesNotCauseFatalError()
  536. {
  537. $this->module->amOnPage('/form/button-not-in-form');
  538. $this->module->click('The Button');
  539. }
  540. public function testSubmitFormWithoutEmptyOptionsInSelect()
  541. {
  542. $this->module->amOnPage('/form/bug3824');
  543. $this->module->submitForm('form', []);
  544. $this->module->dontSee('ERROR');
  545. }
  546. /**
  547. * @issue https://github.com/Codeception/Codeception/issues/3953
  548. */
  549. public function testFillFieldInGetFormWithoutId()
  550. {
  551. $this->module->amOnPage('/form/bug3953');
  552. $this->module->selectOption('select_name', 'two');
  553. $this->module->fillField('search_name', 'searchterm');
  554. $this->module->click('Submit');
  555. $params = data::get('query');
  556. $this->assertEquals('two', $params['select_name']);
  557. $this->assertEquals('searchterm', $params['search_name']);
  558. }
  559. public function testGrabPageSourceWhenNotOnPage()
  560. {
  561. $this->setExpectedException(
  562. '\Codeception\Exception\ModuleException',
  563. 'Page not loaded. Use `$I->amOnPage` (or hidden API methods `_request` and `_loadPage`) to open it'
  564. );
  565. $this->module->grabPageSource();
  566. }
  567. public function testGrabPageSourceWhenOnPage()
  568. {
  569. $this->module->amOnPage('/minimal');
  570. $sourceExpected =
  571. <<<HTML
  572. <!DOCTYPE html>
  573. <html>
  574. <head>
  575. <title>
  576. Minimal page
  577. </title>
  578. </head>
  579. <body>
  580. <h1>
  581. Minimal page
  582. </h1>
  583. </body>
  584. </html>
  585. HTML
  586. ;
  587. $sourceActual = $this->module->grabPageSource();
  588. $this->assertXmlStringEqualsXmlString($sourceExpected, $sourceActual);
  589. }
  590. /**
  591. * @issue https://github.com/Codeception/Codeception/issues/4383
  592. */
  593. public function testSecondAmOnUrlWithEmptyPath()
  594. {
  595. $this->module->amOnUrl('http://localhost:8000/info');
  596. $this->module->see('Lots of valuable data here');
  597. $this->module->amOnUrl('http://localhost:8000');
  598. $this->module->dontSee('Lots of valuable data here');
  599. }
  600. public function testSetUserAgentUsingConfig()
  601. {
  602. $this->module->_setConfig(['headers' => ['User-Agent' => 'Codeception User Agent Test 1.0']]);
  603. $this->module->_initialize();
  604. $this->module->amOnPage('/user-agent');
  605. $response = $this->module->grabPageSource();
  606. $this->assertEquals('Codeception User Agent Test 1.0', $response, 'Incorrect user agent');
  607. }
  608. }