WebDriverTest.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. <?php
  2. use Codeception\Step;
  3. use Codeception\Util\Stub;
  4. use Facebook\WebDriver\Remote\RemoteWebDriver;
  5. use Facebook\WebDriver\WebDriverBy;
  6. use Facebook\WebDriver\WebDriverKeys;
  7. require_once codecept_data_dir() . 'app/data.php';
  8. require_once __DIR__ . '/../unit/Codeception/Module/TestsForBrowsers.php';
  9. class WebDriverTest extends TestsForBrowsers
  10. {
  11. /**
  12. * @var \Codeception\Module\WebDriver
  13. */
  14. protected $module;
  15. /**
  16. * @var RemoteWebDriver
  17. */
  18. protected $webDriver;
  19. const MODULE_CLASS = 'Codeception\Module\WebDriver';
  20. const WEBDRIVER_CLASS = 'Facebook\WebDriver\Remote\RemoteWebDriver';
  21. public function _before()
  22. {
  23. $this->module = $this->getModule('WebDriver');
  24. $this->webDriver = &$this->getModule('WebDriver')->webDriver;
  25. }
  26. public function _after()
  27. {
  28. data::clean();
  29. }
  30. public function testClickEventOnCheckbox()
  31. {
  32. $this->module->amOnPage('/form/checkbox');
  33. $this->module->uncheckOption('#checkin');
  34. $this->module->dontSee('ticked', '#notice');
  35. $this->module->checkOption('#checkin');
  36. $this->module->see('ticked', '#notice');
  37. }
  38. public function testAcceptPopup()
  39. {
  40. $this->notForPhantomJS();
  41. $this->module->amOnPage('/form/popup');
  42. $this->module->click('Confirm');
  43. $this->module->acceptPopup();
  44. $this->module->see('Yes', '#result');
  45. }
  46. public function testCancelPopup()
  47. {
  48. $this->notForPhantomJS();
  49. $this->module->amOnPage('/form/popup');
  50. $this->module->click('Confirm');
  51. $this->module->cancelPopup();
  52. $this->module->see('No', '#result');
  53. }
  54. public function testSelectByCss()
  55. {
  56. $this->module->amOnPage('/form/select');
  57. $this->module->selectOption('form select[name=age]', '21-60');
  58. $this->module->click('Submit');
  59. $form = data::get('form');
  60. $this->assertEquals('adult', $form['age']);
  61. }
  62. public function testSelectInvalidOptionForSecondSelectFails()
  63. {
  64. $this->shouldFail();
  65. $this->module->amOnPage('/form/select_second');
  66. $this->module->selectOption('#select2', 'Value2');
  67. }
  68. public function testSeeInPopup()
  69. {
  70. $this->notForPhantomJS();
  71. $this->module->amOnPage('/form/popup');
  72. $this->module->click('Alert');
  73. $this->module->seeInPopup('Really?');
  74. $this->module->cancelPopup();
  75. }
  76. public function testScreenshot()
  77. {
  78. $this->module->amOnPage('/');
  79. @unlink(\Codeception\Configuration::outputDir().'testshot.png');
  80. $testName="debugTest";
  81. $this->module->makeScreenshot($testName);
  82. $this->assertFileExists(\Codeception\Configuration::outputDir().'debug/'.$testName.'.png');
  83. @unlink(\Codeception\Configuration::outputDir().'debug/'.$testName.'.png');
  84. $this->module->_saveScreenshot(\Codeception\Configuration::outputDir().'testshot.png');
  85. $this->assertFileExists(\Codeception\Configuration::outputDir().'testshot.png');
  86. @unlink(\Codeception\Configuration::outputDir().'testshot.png');
  87. }
  88. public function testSubmitForm()
  89. {
  90. $this->module->amOnPage('/form/complex');
  91. $this->module->submitForm('form', [
  92. 'name' => 'Davert',
  93. 'age' => 'child',
  94. 'terms' => 'agree',
  95. 'description' => 'My Bio'
  96. ]);
  97. $form = data::get('form');
  98. $this->assertEquals('Davert', $form['name']);
  99. $this->assertEquals('kill_all', $form['action']);
  100. $this->assertEquals('My Bio', $form['description']);
  101. $this->assertEquals('agree', $form['terms']);
  102. $this->assertEquals('child', $form['age']);
  103. }
  104. public function testSubmitFormWithNumbers()
  105. {
  106. $this->module->amOnPage('/form/complex');
  107. $this->module->submitForm('form', [
  108. 'name' => 'Davert',
  109. 'age' => 'child',
  110. 'terms' => 'agree',
  111. 'description' => 10
  112. ]);
  113. $form = data::get('form');
  114. $this->assertEquals('Davert', $form['name']);
  115. $this->assertEquals('kill_all', $form['action']);
  116. $this->assertEquals('10', $form['description']);
  117. $this->assertEquals('agree', $form['terms']);
  118. $this->assertEquals('child', $form['age']);
  119. }
  120. /**
  121. * @dataProvider strictSelectorProvider
  122. */
  123. public function testSubmitFormWithButtonAsStrictSelector(array $selector)
  124. {
  125. $this->module->amOnPage('/form/strict_selectors');
  126. $this->module->submitForm('form', [
  127. 'name' => 'Davert',
  128. 'age' => 'child',
  129. 'terms' => 'agree',
  130. 'description' => 'My Bio'
  131. ], $selector);
  132. $form = data::get('form');
  133. $this->assertEquals('Davert', $form['name']);
  134. $this->assertEquals('kill_all', $form['action']);
  135. $this->assertEquals('My Bio', $form['description']);
  136. $this->assertEquals('agree', $form['terms']);
  137. $this->assertEquals('child', $form['age']);
  138. }
  139. public function strictSelectorProvider()
  140. {
  141. return [
  142. 'by id' => [['id' => 'submit_button']],
  143. 'by name' => [['name' => 'submit_button_name']],
  144. 'by css' => [['css' => 'form #submit_button']],
  145. 'by xpath' => [['xpath' => '//*[@id="submit_button"]']],
  146. 'by link' => [['link' => 'Submit']],
  147. 'by class' => [['class' => 'button']],
  148. ];
  149. }
  150. /**
  151. * @dataProvider webDriverByProvider
  152. */
  153. public function testSubmitFormWithButtonAsWebDriverBy(WebDriverBy $selector)
  154. {
  155. $this->module->amOnPage('/form/strict_selectors');
  156. $this->module->submitForm('form', [
  157. 'name' => 'Davert',
  158. 'age' => 'child',
  159. 'terms' => 'agree',
  160. 'description' => 'My Bio'
  161. ], $selector);
  162. $form = data::get('form');
  163. $this->assertEquals('Davert', $form['name']);
  164. $this->assertEquals('kill_all', $form['action']);
  165. $this->assertEquals('My Bio', $form['description']);
  166. $this->assertEquals('agree', $form['terms']);
  167. $this->assertEquals('child', $form['age']);
  168. }
  169. public function webDriverByProvider()
  170. {
  171. return [
  172. 'by id' => [WebDriverBy::id('submit_button')],
  173. 'by name' => [WebDriverBy::name('submit_button_name')],
  174. 'by css selector' => [WebDriverBy::cssSelector('form #submit_button')],
  175. 'by xpath' => [WebDriverBy::xpath('//*[@id="submit_button"]')],
  176. 'by link text' => [WebDriverBy::linkText('Submit')],
  177. 'by class name' => [WebDriverBy::className('button')],
  178. ];
  179. }
  180. public function testRadioButtonByValue()
  181. {
  182. $this->module->amOnPage('/form/radio');
  183. $this->module->selectOption('form', 'disagree');
  184. $this->module->click('Submit');
  185. $form = data::get('form');
  186. $this->assertEquals('disagree', $form['terms']);
  187. }
  188. public function testRadioButtonByLabelOnContext()
  189. {
  190. $this->module->amOnPage('/form/radio');
  191. $this->module->selectOption('form input', 'Get Off');
  192. $this->module->seeOptionIsSelected('form input', 'disagree');
  193. $this->module->dontSeeOptionIsSelected('form input', 'agree');
  194. $this->module->click('Submit');
  195. $form = data::get('form');
  196. $this->assertEquals('disagree', $form['terms']);
  197. }
  198. public function testRadioButtonByLabel()
  199. {
  200. $this->module->amOnPage('/form/radio');
  201. $this->module->checkOption('Get Off');
  202. $this->module->click('Submit');
  203. $form = data::get('form');
  204. $this->assertEquals('disagree', $form['terms']);
  205. }
  206. public function testRawSelenium()
  207. {
  208. $this->module->amOnPage('/');
  209. $this->module->executeInSelenium(function ($webdriver) {
  210. $webdriver->findElement(WebDriverBy::id('link'))->click();
  211. });
  212. $this->module->seeCurrentUrlEquals('/info');
  213. }
  214. public function testKeys()
  215. {
  216. $this->module->amOnPage('/form/field');
  217. $this->module->pressKey('#name', ['ctrl', 'a'], WebDriverKeys::DELETE);
  218. $this->module->pressKey('#name', 'test', ['shift', '111']);
  219. $this->module->pressKey('#name', '1');
  220. $this->module->seeInField('#name', 'test!!!1');
  221. }
  222. public function testWait()
  223. {
  224. $this->module->amOnPage('/');
  225. $time = time();
  226. $this->module->wait(3);
  227. $this->assertGreaterThanOrEqual($time+3, time());
  228. }
  229. public function testSelectInvalidOptionFails()
  230. {
  231. $this->shouldFail();
  232. $this->module->amOnPage('/form/select');
  233. $this->module->selectOption('#age', '13-22');
  234. }
  235. public function testAppendFieldSelect()
  236. {
  237. $this->module->amOnPage('/form/select_multiple');
  238. $this->module->selectOption('form #like', 'eat');
  239. $this->module->appendField('form #like', 'code');
  240. $this->module->click('Submit');
  241. $form = data::get('form');
  242. $this->assertEmpty(array_diff($form['like'], ["eat", "code"]));
  243. }
  244. public function testAppendFieldSelectFails()
  245. {
  246. $this->shouldFail();
  247. $this->module->amOnPage('/form/select_multiple');
  248. $this->module->appendField('form #like', 'code123');
  249. }
  250. public function testAppendFieldTextarea()
  251. {
  252. $this->module->amOnPage('/form/textarea');
  253. $this->module->fillField('form #description', 'eat');
  254. $this->module->appendField('form #description', ' code');
  255. $this->module->click('Submit');
  256. $form = data::get('form');
  257. $this->assertEquals('eat code', $form['description']);
  258. }
  259. public function testAppendFieldTextareaFails()
  260. {
  261. $this->shouldFail();
  262. $this->module->amOnPage('/form/textarea');
  263. $this->module->appendField('form #description123', ' code');
  264. }
  265. public function testAppendFieldText()
  266. {
  267. $this->module->amOnPage('/form/field');
  268. $this->module->appendField('form #name', ' code');
  269. $this->module->click('Submit');
  270. $form = data::get('form');
  271. $this->assertEquals('OLD_VALUE code', $form['name']);
  272. }
  273. public function testAppendFieldTextFails()
  274. {
  275. $this->shouldFail();
  276. $this->module->amOnPage('/form/field');
  277. $this->module->appendField('form #name123', ' code');
  278. }
  279. public function testAppendFieldCheckboxByValue()
  280. {
  281. $this->module->amOnPage('/form/checkbox');
  282. $this->module->appendField('form input[name=terms]', 'agree');
  283. $this->module->click('Submit');
  284. $form = data::get('form');
  285. $this->assertEquals('agree', $form['terms']);
  286. }
  287. public function testAppendFieldCheckboxByValueFails()
  288. {
  289. $this->shouldFail();
  290. $this->module->amOnPage('/form/checkbox');
  291. $this->module->appendField('form input[name=terms]', 'agree123');
  292. }
  293. public function testAppendFieldCheckboxByLabel()
  294. {
  295. $this->module->amOnPage('/form/checkbox');
  296. $this->module->appendField('form input[name=terms]', 'I Agree');
  297. $this->module->click('Submit');
  298. $form = data::get('form');
  299. $this->assertEquals('agree', $form['terms']);
  300. }
  301. public function testAppendFieldCheckboxByLabelFails()
  302. {
  303. $this->shouldFail();
  304. $this->module->amOnPage('/form/checkbox');
  305. $this->module->appendField('form input[name=terms]', 'I Agree123');
  306. }
  307. public function testAppendFieldRadioButtonByValue()
  308. {
  309. $this->module->amOnPage('/form/radio');
  310. $this->module->appendField('form input[name=terms]', 'disagree');
  311. $this->module->click('Submit');
  312. $form = data::get('form');
  313. $this->assertEquals('disagree', $form['terms']);
  314. }
  315. public function testAppendFieldRadioButtonByValueFails()
  316. {
  317. $this->shouldFail();
  318. $this->module->amOnPage('/form/radio');
  319. $this->module->appendField('form input[name=terms]', 'disagree123');
  320. }
  321. public function testAppendFieldRadioButtonByLabel()
  322. {
  323. $this->module->amOnPage('/form/radio');
  324. $this->module->appendField('form input[name=terms]', 'Get Off');
  325. $this->module->click('Submit');
  326. $form = data::get('form');
  327. $this->assertEquals('disagree', $form['terms']);
  328. }
  329. public function testAppendFieldRadioButtonByLabelFails()
  330. {
  331. $this->shouldFail();
  332. $this->module->amOnPage('/form/radio');
  333. $this->module->appendField('form input[name=terms]', 'Get Off123');
  334. }
  335. public function testPauseExecution()
  336. {
  337. $this->module->amOnPage('/');
  338. $this->module->pauseExecution();
  339. }
  340. // Issue https://github.com/Codeception/Codeception/pull/875
  341. public function testFillPasswordOnFormSubmit()
  342. {
  343. $this->module->amOnPage('/form/complex');
  344. $this->module->submitForm('form', [
  345. 'password' => '123456'
  346. ]);
  347. $form = data::get('form');
  348. $this->assertEquals('123456', $form['password']);
  349. }
  350. public function testEmptyFormSubmit()
  351. {
  352. $this->shouldFail();
  353. $this->module->amOnPage('/form/complex');
  354. $this->module->submitForm('form111', []);
  355. }
  356. public function testWebDriverByLocators()
  357. {
  358. $this->module->amOnPage('/login');
  359. $this->module->seeElement(WebDriverBy::id('submit-label'));
  360. $this->module->seeElement(WebDriverBy::name('password'));
  361. $this->module->seeElement(WebDriverBy::className('optional'));
  362. $this->module->seeElement(WebDriverBy::cssSelector('form.global_form_box'));
  363. $this->module->seeElement(WebDriverBy::xpath(\Codeception\Util\Locator::tabIndex(4)));
  364. $this->module->fillField(WebDriverBy::name('password'), '123456');
  365. $this->module->amOnPage('/form/select');
  366. $this->module->selectOption(WebDriverBy::name('age'), 'child');
  367. $this->module->amOnPage('/form/checkbox');
  368. $this->module->checkOption(WebDriverBy::name('terms'));
  369. $this->module->amOnPage('/');
  370. $this->module->seeElement(WebDriverBy::linkText('Test'));
  371. $this->module->click(WebDriverBy::linkText('Test'));
  372. $this->module->seeCurrentUrlEquals('/form/hidden');
  373. }
  374. public function testSeeVisible()
  375. {
  376. $this->module->amOnPage('/info');
  377. $this->module->dontSee('Invisible text');
  378. $this->module->dontSee('Invisible', '.hidden');
  379. $this->module->seeInPageSource('Invisible text');
  380. }
  381. public function testSeeInvisible()
  382. {
  383. $this->shouldFail();
  384. $this->module->amOnPage('/info');
  385. $this->module->see('Invisible text');
  386. }
  387. public function testFailWebDriverByLocator()
  388. {
  389. $this->shouldFail();
  390. $this->module->amOnPage('/form/checkbox');
  391. $this->module->checkOption(WebDriverBy::name('age'));
  392. }
  393. // fails in PhpBrowser :(
  394. public function testSubmitUnchecked()
  395. {
  396. $this->module->amOnPage('/form/unchecked');
  397. $this->module->seeCheckboxIsChecked('#checkbox');
  398. $this->module->uncheckOption('#checkbox');
  399. $this->module->click('#submit');
  400. ;
  401. $this->module->see('0', '#notice');
  402. }
  403. public function testCreateCeptScreenshotFail()
  404. {
  405. $fakeWd = Stub::make('\Facebook\WebDriver\Remote\RemoteWebDriver', [
  406. 'takeScreenshot' => Stub::once(function () {
  407. }),
  408. 'getPageSource' => Stub::once(function () {
  409. }),
  410. 'manage' => Stub::make('\Facebook\WebDriver\WebDriverOptions', [
  411. 'getAvailableLogTypes' => Stub::atLeastOnce(function () {
  412. return [];
  413. }),
  414. ]),
  415. ]);
  416. $module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
  417. $cept = (new \Codeception\Test\Cept('loginCept', 'loginCept.php'));
  418. $module->_failed($cept, new PHPUnit_Framework_AssertionFailedError());
  419. }
  420. public function testCreateCestScreenshotOnFail()
  421. {
  422. $fakeWd = Stub::make(self::WEBDRIVER_CLASS, [
  423. 'takeScreenshot' => Stub::once(function ($filename) {
  424. PHPUnit_Framework_Assert::assertEquals(codecept_log_dir('stdClass.login.fail.png'), $filename);
  425. }),
  426. 'getPageSource' => Stub::once(function () {
  427. }),
  428. 'manage' => Stub::make('\Facebook\WebDriver\WebDriverOptions', [
  429. 'getAvailableLogTypes' => Stub::atLeastOnce(function () {
  430. return [];
  431. }),
  432. ]),
  433. ]);
  434. $module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
  435. $cest = new \Codeception\Test\Cest(new stdClass(), 'login', 'someCest.php');
  436. $module->_failed($cest, new PHPUnit_Framework_AssertionFailedError());
  437. }
  438. public function testCreateTestScreenshotOnFail()
  439. {
  440. $test = Stub::make('\Codeception\TestCase\Test', ['getName' => 'testLogin']);
  441. $fakeWd = Stub::make(self::WEBDRIVER_CLASS, [
  442. 'takeScreenshot' => Stub::once(function ($filename) use ($test) {
  443. PHPUnit_Framework_Assert::assertEquals(
  444. codecept_log_dir(get_class($test).'.testLogin.fail.png'),
  445. $filename
  446. );
  447. }),
  448. 'getPageSource' => Stub::once(function () {
  449. }),
  450. 'manage' => Stub::make('\Facebook\WebDriver\WebDriverOptions', [
  451. 'getAvailableLogTypes' => Stub::atLeastOnce(function () {
  452. return [];
  453. }),
  454. ]),
  455. ]);
  456. $module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
  457. $module->_failed($test, new PHPUnit_Framework_AssertionFailedError());
  458. }
  459. public function testWebDriverWaits()
  460. {
  461. $fakeWd = Stub::make(self::WEBDRIVER_CLASS, ['wait' => Stub::exactly(12, function () {
  462. return new \Codeception\Util\Maybe();
  463. })]);
  464. $module = Stub::make(self::MODULE_CLASS, ['webDriver' => $fakeWd]);
  465. $module->waitForElement(WebDriverBy::partialLinkText('yeah'));
  466. $module->waitForElement(['id' => 'user']);
  467. $module->waitForElement(['css' => '.user']);
  468. $module->waitForElement('//xpath');
  469. $module->waitForElementVisible(WebDriverBy::partialLinkText('yeah'));
  470. $module->waitForElementVisible(['id' => 'user']);
  471. $module->waitForElementVisible(['css' => '.user']);
  472. $module->waitForElementVisible('//xpath');
  473. $module->waitForElementNotVisible(WebDriverBy::partialLinkText('yeah'));
  474. $module->waitForElementNotVisible(['id' => 'user']);
  475. $module->waitForElementNotVisible(['css' => '.user']);
  476. $module->waitForElementNotVisible('//xpath');
  477. }
  478. public function testBug1467()
  479. {
  480. $this->module->amOnPage('/form/bug1467');
  481. $this->module->selectOption('form[name=form2] input[name=first_test_radio]', 'Yes');
  482. $this->module->selectOption('form[name=form2] input[name=second_test_radio]', 'No');
  483. $this->module->seeOptionIsSelected('form[name=form2] input[name=first_test_radio]', 'Yes');
  484. $this->module->seeOptionIsSelected('form[name=form2] input[name=second_test_radio]', 'No');
  485. // shouldn't have touched form1 at all
  486. $this->module->dontSeeOptionIsSelected('form[name=form1] input[name=first_test_radio]', 'No');
  487. $this->module->dontSeeOptionIsSelected('form[name=form1] input[name=first_test_radio]', 'Yes');
  488. $this->module->dontSeeOptionIsSelected('form[name=form1] input[name=second_test_radio]', 'No');
  489. $this->module->dontSeeOptionIsSelected('form[name=form1] input[name=second_test_radio]', 'Yes');
  490. }
  491. /**
  492. * @Issue 1598
  493. */
  494. public function testWaitForTextBug1598()
  495. {
  496. $this->module->amOnPage('/form/bug1598');
  497. $this->module->waitForText('12,345', 10, '#field');
  498. }
  499. public function testSeeElementMalformedWdLocator()
  500. {
  501. $this->setExpectedException('Codeception\Exception\MalformedLocatorException');
  502. $this->module->amOnPage('/');
  503. $this->module->seeElement(WebDriverBy::xpath('H---EY!'));
  504. }
  505. public function testBug1637()
  506. {
  507. $this->module->amOnPage('/form/bug1637');
  508. // confirm that options outside a form are still selectable
  509. $this->module->selectOption('input[name=first_test_radio]', 'Yes');
  510. // confirm that it did what we expected and did not do anything else
  511. $this->module->seeOptionIsSelected('input[name=first_test_radio]', 'Yes');
  512. $this->module->dontSeeOptionIsSelected('input[name=first_test_radio]', 'No');
  513. }
  514. public function testBug2046()
  515. {
  516. $this->module->webDriver = null;
  517. $this->module->_saveScreenshot(\Codeception\Configuration::outputDir().'testshot.png');
  518. }
  519. public function testSessionSnapshots()
  520. {
  521. $this->notForPhantomJS();
  522. $this->module->amOnPage('/');
  523. $this->module->setCookie('PHPSESSID', '123456', ['path' => '/']);
  524. $this->module->saveSessionSnapshot('login');
  525. $this->module->seeCookie('PHPSESSID');
  526. $this->webDriver->manage()->deleteAllCookies();
  527. $this->module->dontSeeCookie('PHPSESSID');
  528. $this->module->loadSessionSnapshot('login');
  529. $this->module->seeCookie('PHPSESSID');
  530. }
  531. public function testSaveSessionSnapshotsExcludeInvalidCookieDomains()
  532. {
  533. $this->notForPhantomJS();
  534. $fakeWdOptions = Stub::make('\Facebook\WebDriver\WebDriverOptions', [
  535. 'getCookies' => Stub::atLeastOnce(function () {
  536. return [
  537. [
  538. 'name' => 'PHPSESSID',
  539. 'value' => '123456',
  540. 'path' => '/',
  541. ],
  542. [
  543. 'name' => '3rdParty',
  544. 'value' => '_value_',
  545. 'path' => '/',
  546. 'domain' => '.3rd-party.net',
  547. ]
  548. ];
  549. }),
  550. ]);
  551. $fakeWd = Stub::make(self::WEBDRIVER_CLASS, [
  552. 'manage' => Stub::atLeastOnce(function () use ($fakeWdOptions) {
  553. return $fakeWdOptions;
  554. }),
  555. ]);
  556. // Mock the WebDriverOptions::getCookies() method on the first call to introduce a 3rd-party cookie
  557. // which has to be ignored when saving a snapshot.
  558. $originalWebDriver = $this->module->webDriver;
  559. $this->module->webDriver = $fakeWd;
  560. $this->module->seeCookie('PHPSESSID');
  561. $this->module->seeCookie('3rdParty');
  562. $this->module->saveSessionSnapshot('login');
  563. // Restore the original WebDriver
  564. $this->module->webDriver = $originalWebDriver;
  565. $this->webDriver->manage()->deleteAllCookies();
  566. $this->module->dontSeeCookie('PHPSESSID');
  567. $this->module->dontSeeCookie('3rdParty');
  568. $this->module->loadSessionSnapshot('login');
  569. $this->module->seeCookie('PHPSESSID');
  570. $this->module->dontSeeCookie('3rdParty');
  571. }
  572. public function testSeeInFieldTextarea()
  573. {
  574. $this->module->amOnPage('/form/textarea');
  575. //make sure we see 'sunrise' which is the default text in the textarea
  576. $this->module->seeInField('#description', 'sunrise');
  577. if ($this->notForSelenium()) {
  578. $this->module->seeInField('#whitespaces', ' no_whitespaces ');
  579. }
  580. $this->module->seeInField('#whitespaces', 'no_whitespaces');
  581. //fill in some new text and see if we can see it
  582. $textarea_value = 'test string';
  583. $this->module->fillField('#description', $textarea_value);
  584. $this->module->seeInField('#description', $textarea_value);
  585. }
  586. public function testSeeInFieldSelect()
  587. {
  588. $this->module->amOnPage('/form/select_second');
  589. if ($this->notForSelenium()) {
  590. $this->module->seeInField('#select2', ' no_whitespaces ');
  591. }
  592. $this->module->seeInField('#select2', 'no_whitespaces');
  593. // select new option and check it
  594. $option_value = 'select2_value1';
  595. $this->module->selectOption('#select2', $option_value);
  596. $this->module->seeInField('#select2', $option_value);
  597. }
  598. public function testAppendFieldDiv()
  599. {
  600. $this->notForPhantomJS();
  601. $this->module->amOnPage('/form/div_content_editable');
  602. //make sure we see 'sunrise' which is the default text in the textarea
  603. $this->module->see('sunrise', '#description');
  604. //fill in some new text and see if we can see it
  605. $textarea_value = 'moonrise';
  606. $this->module->appendField('#description', $textarea_value);
  607. $this->module->see('sunrise' . $textarea_value, '#description');
  608. }
  609. public function testOpenPageException()
  610. {
  611. if (!$this->module->_getConfig('restart')) {
  612. $this->markTestSkipped('works only on restarts');
  613. }
  614. parent::testOpenPageException();
  615. }
  616. public function testCookies()
  617. {
  618. $this->notForPhantomJS();
  619. parent::testCookies();
  620. }
  621. public function testSendingCookies()
  622. {
  623. $this->notForPhantomJS();
  624. parent::testSendingCookies();
  625. }
  626. public function testCookiesWithPath()
  627. {
  628. $this->notForPhantomJS();
  629. parent::testCookiesWithPath();
  630. }
  631. protected function notForPhantomJS()
  632. {
  633. if ($this->module->_getConfig('browser') == 'phantomjs') {
  634. $this->markTestSkipped('does not work for phantomjs');
  635. }
  636. }
  637. protected function notForSelenium()
  638. {
  639. if ($this->module->_getConfig('browser') != 'phantom') {
  640. $this->markTestSkipped('does not work for selenium');
  641. }
  642. }
  643. public function testScrollTo()
  644. {
  645. $this->module->amOnPage('/form/example18');
  646. $this->module->scrollTo('#clickme');
  647. $this->module->click('Submit');
  648. $this->module->see('Welcome to test app!');
  649. }
  650. /**
  651. * @Issue 2921
  652. */
  653. public function testSeeInFieldForTextarea()
  654. {
  655. $this->module->amOnPage('/form/bug2921');
  656. $this->module->seeInField('foo', 'bar baz');
  657. }
  658. public function testClickHashLink()
  659. {
  660. $this->module->amOnPage('/form/anchor');
  661. $this->module->click('Hash Link');
  662. $this->module->seeCurrentUrlEquals('/form/anchor#b');
  663. }
  664. /**
  665. * @Issue 3865
  666. */
  667. public function testClickNumericLink()
  668. {
  669. $this->module->amOnPage('/form/bug3865');
  670. $this->module->click('222');
  671. $this->module->see('Welcome to test app');
  672. }
  673. public function testClickHashButton()
  674. {
  675. $this->module->amOnPage('/form/anchor');
  676. $this->module->click('Hash Button');
  677. $this->module->seeCurrentUrlEquals('/form/anchor#c');
  678. }
  679. public function testSubmitHashForm()
  680. {
  681. $this->module->amOnPage('/form/anchor');
  682. $this->module->click('Hash Form');
  683. $this->module->seeCurrentUrlEquals('/form/anchor#a');
  684. }
  685. public function testJSErrorLoggingPositive()
  686. {
  687. // arrange
  688. $this->module->_setConfig(['log_js_errors' => true]);
  689. $cept = new \Codeception\Test\Cept('foo', 'bar');
  690. // act
  691. $this->module->amOnPage('/jserroronload');
  692. $this->module->_failed($cept, 'anyFailMessage');
  693. // assert
  694. /* @var $steps Step[] */
  695. $steps = $cept->getScenario()->getSteps();
  696. $this->assertGreaterThan(0, count($steps));
  697. $lastStep = end($steps);
  698. $this->assertContains(
  699. "TypeError",
  700. $lastStep->getHtml()
  701. );
  702. }
  703. public function testJSErrorLoggingNegative()
  704. {
  705. // arrange
  706. $this->module->_setConfig(['log_js_errors' => false]);
  707. $cept = new \Codeception\Test\Cept('foo', 'bar');
  708. // act
  709. $this->module->amOnPage('/jserroronload');
  710. $this->module->_failed($cept, 'anyFailMessage');
  711. // assert
  712. /* @var $steps Step[] */
  713. $steps = $cept->getScenario()->getSteps();
  714. $this->assertEquals(0, count($steps));
  715. }
  716. public function testMoveMouseOver()
  717. {
  718. $this->module->amOnPage('/form/click');
  719. $this->module->moveMouseOver(null, 123, 88);
  720. $this->module->clickWithLeftButton(null, 0, 0);
  721. $this->module->see('click, offsetX: 123 - offsetY: 88');
  722. $this->module->moveMouseOver(null, 10, 10);
  723. $this->module->clickWithLeftButton(null, 0, 0);
  724. $this->module->see('click, offsetX: 133 - offsetY: 98');
  725. $this->module->moveMouseOver('#element2');
  726. $this->module->clickWithLeftButton(null, 0, 0);
  727. $this->module->see('click, offsetX: 58 - offsetY: 158');
  728. $this->module->moveMouseOver('#element2', 0, 0);
  729. $this->module->clickWithLeftButton(null, 0, 0);
  730. $this->module->see('click, offsetX: 8 - offsetY: 108');
  731. }
  732. public function testLeftClick()
  733. {
  734. $this->module->amOnPage('/form/click');
  735. $this->module->clickWithLeftButton(null, 123, 88);
  736. $this->module->see('click, offsetX: 123 - offsetY: 88');
  737. $this->module->clickWithLeftButton('body');
  738. $this->module->see('click, offsetX: 600 - offsetY: 384');
  739. $this->module->clickWithLeftButton('body', 50, 75);
  740. $this->module->see('click, offsetX: 58 - offsetY: 83');
  741. $this->module->clickWithLeftButton('body div');
  742. $this->module->see('click, offsetX: 58 - offsetY: 58');
  743. $this->module->clickWithLeftButton('#element2', 70, 75);
  744. $this->module->see('click, offsetX: 78 - offsetY: 183');
  745. }
  746. public function testRightClick()
  747. {
  748. // actually not supported in phantomjs see https://github.com/ariya/phantomjs/issues/14005
  749. $this->notForPhantomJS();
  750. $this->module->amOnPage('/form/click');
  751. $this->module->clickWithRightButton(null, 123, 88);
  752. $this->module->see('context, offsetX: 123 - offsetY: 88');
  753. $this->module->clickWithRightButton('body');
  754. $this->module->see('context, offsetX: 600 - offsetY: 384');
  755. $this->module->clickWithRightButton('body', 50, 75);
  756. $this->module->see('context, offsetX: 58 - offsetY: 83');
  757. $this->module->clickWithRightButton('body div');
  758. $this->module->see('context, offsetX: 58 - offsetY: 58');
  759. $this->module->clickWithRightButton('#element2', 70, 75);
  760. $this->module->see('context, offsetX: 78 - offsetY: 183');
  761. }
  762. public function testBrowserTabs()
  763. {
  764. $this->notForPhantomJS();
  765. $this->module->amOnPage('/form/example1');
  766. $this->module->openNewTab();
  767. $this->module->amOnPage('/form/example2');
  768. $this->module->openNewTab();
  769. $this->module->amOnPage('/form/example3');
  770. $this->module->openNewTab();
  771. $this->module->amOnPage('/form/example4');
  772. $this->module->openNewTab();
  773. $this->module->amOnPage('/form/example5');
  774. $this->module->closeTab();
  775. $this->module->seeInCurrentUrl('example4');
  776. $this->module->switchToPreviousTab(2);
  777. $this->module->seeInCurrentUrl('example2');
  778. $this->module->switchToNextTab();
  779. $this->module->seeInCurrentUrl('example3');
  780. $this->module->closeTab();
  781. $this->module->seeInCurrentUrl('example2');
  782. $this->module->switchToNextTab(2);
  783. $this->module->seeInCurrentUrl('example1');
  784. }
  785. }