PhpBrowserTest.php 24 KB

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