Warning: file(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php on line 40

Warning: file(https://scipilot.org/blog/wp-content/plugins/ap-extended-mime-types/mime-types.txt): Failed to open stream: no suitable wrapper could be found in /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php on line 40

Warning: foreach() argument must be of type array|object, false given in /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php on line 42

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909

Warning: Cannot modify header information - headers already sent by (output started at /home/sciptorg/public_html/blog/wp-content/plugins/ap-extended-mime-types/ap-extended-mime-types.php:40) in /home/sciptorg/public_html/blog/wp-includes/rest-api/class-wp-rest-server.php on line 1909
{"id":405,"date":"2016-06-29T12:59:08","date_gmt":"2016-06-29T01:59:08","guid":{"rendered":"http:\/\/scipilot.org\/blog\/?p=405"},"modified":"2016-06-29T12:59:08","modified_gmt":"2016-06-29T01:59:08","slug":"phpunit-selenium2-cheat-sheet","status":"publish","type":"post","link":"https:\/\/scipilot.org\/blog\/2016\/06\/29\/phpunit-selenium2-cheat-sheet\/","title":{"rendered":"PHPUnit-Selenium2 Cheat Sheet"},"content":{"rendered":"

My PHPUnit-Selenium2 Cheat Sheet<\/strong><\/h1>\n

Here are a few snippets of how I’ve achieved various tasks, some tricks and patterns\u00a0in phpunit\/phpunit-selenium v2.0 – targeting Selenium2. I’ll try to keep this updated with more techniques over time.<\/p>\n

Screenshots<\/strong><\/p>\n

I wrote this small hook\u00a0to make screenshots automatic, like they used to be. Of course you may want to put a timestamp in the file, but I usually only\u00a0want the last problem.<\/p>\n

\/**\r\n * PhpUnitSelenium v1 used to have automatic screenshot as a feature, in v2 you have to do it \"manually\".\r\n *\/\r\npublic function onNotSuccessfulTest(Exception $e){\r\n file_put_contents(__DIR__.'\/..\/..\/out\/screenshots\/screenshot1.png', $this->currentScreenshot());\r\n\r\n parent::onNotSuccessfulTest($e);\r\n}\r\n<\/pre>\n

Waiting for stuff<\/strong><\/p>\n

An eternal issue in automated testing is latency and timeouts. Particularly problematic in anything other than a standard onclick-pageload cycle, such as pop-up calendars or a JS app. Again I felt the move from Selenium1 to 2 made this much more clumsy, so I wrote this simple wrapper for the common wait pattern boilerplate.<\/p>\n

\/**\r\n * Utility method to wait for an element to appear.\r\n *\r\n * @param string $selector\r\n * @param int    $timeout milliseconds wait cap, after which you'll get an error\r\n *\/\r\nprotected function waitFor($selector, $timeout=self::WAIT_TIMEOUT_MS){\r\n $this->waitUntil(function(PHPUnit_Extensions_Selenium2TestCase $testCase) use($selector){\r\n  try {\r\n   $testCase->byCssSelector($selector);\r\n  } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {\r\n   return null;\r\n  }\r\n  return true;\r\n }, $timeout);\r\n}\r\n\r\n<\/pre>\n

Checking for the right page, reliably.<\/strong><\/p>\n

If something goes wrong in a complex test\u00a0with lots of interactions, it’s important to fail fast<\/em> \u00a0– for example if the wrong page loads, nothing else will work very well. So I always check the page being tested is the right page<\/em>.\u00a0To do this reliably, not using content or design-specific elements, I add a <body> tag “id” attribute to every page (you could use body class if you’re already using that styling technique but I tend to separate my QA tagging from CSS dependencies). Then I added this assertion\u00a0to my base test case.<\/p>\n

\/**\r\n * We use <body id=\"XXX\"> to identify pages reliably.\r\n * @param $id\r\n *\/\r\nprotected function assertBodyIDEquals($id){\r\n $this->assertEquals($id, $this->byCssSelector('body')->attribute('id'));\r\n}<\/pre>\n

Getting Value<\/strong><\/p>\n

The ->value() method was\u00a0removed in Selenium v2.42.0. The replacement method\u00a0is to use $element->attribute(‘value’) [source<\/a>]<\/p>\n

\/\/ old way\r\n\/\/$sCurrentStimulus = $this->byName('word_index')->value();\r\n\/\/ new way\r\n$sCurrentStimulus = $this->byName('word_index')->attribute('value');\r\n\/\/ I actually use this now:\r\n$sCurrentStimulus = $this->byCssSelector('input[name=word_index]')->attribute('value');<\/pre>\n

However ->value() was also a mutator (setter), which ->attribute() is not. So if you want to update<\/em> a value, people say<\/a>\u00a0you have to resort to injecting JavaScript into the page, which I found somewhat distasteful. However luckily this is not the case for the “value” attribute specifically,\u00a0according to the source code, it’s only the GET<\/span> which was removed from ->value().<\/p>\n

JSON Wire Protocol only supports POST to \/value now. To get the value of an element GET \/attribute\/:naem should be used<\/p><\/blockquote>\n

So I\u00a0can carry on doing this, presumably until the next update breaks everything.<\/p>\n

$this->byName('u_first_name')->value(GeneralFixtures::VAlID_SUBJECT_USERNAME);\r\n\r\n\r\n<\/pre>\n

General Page Tests<\/strong><\/p>\n

I have one test suite that just whips through a list of all known pages on a site and scans them for errors, a visual regression smoke test for really stupid\u00a0errors. It’s also easy to drop a call to this method in at the beginning of any test. When I spot other visual errors occurring, I can add them to the list.<\/p>\n

\/**\r\n * Looks for in-page errors.\r\n *\/\r\nprotected function checkErrors() {\r\n $txt = $this->byTag('body')->text();\r\n $src = $this->source();\r\n\r\n \/\/ Removed: This false-positives on the news page.\r\n \/\/$this->assertNotContains('error', $this->byTag('body')->text());\r\n\r\n \/\/ Standard CI errors\r\n $this->assertNotContains('A Database Error Occurred', $txt);\r\n $this->assertNotContains('404 Page Not Found', $txt);\r\n $this->assertNotContains('An Error Was Encountered', $txt);\r\n \/\/ PHP errors\r\n $this->assertNotContains('Fatal error: :', $txt);\r\n $this->assertNotContains('Parse error:', $txt);\r\n\r\n \/\/ the source might have hidden errors, but then it also might contain the word error? false positive?\r\n \/\/ This false positives in the user form (must have validation error text!\r\n \/\/$this->assertNotContains('error', $this->source());\r\n $this->assertNotContains('xdebug-error', $src); \/\/ XDebug wrapper class\r\n\r\n}<\/pre>\n

 <\/p>\n","protected":false},"excerpt":{"rendered":"

My PHPUnit-Selenium2 Cheat Sheet Here are a few snippets of how I’ve achieved various tasks, some tricks and patterns\u00a0in phpunit\/phpunit-selenium v2.0 – targeting Selenium2. I’ll try to keep this updated with more techniques over time. Screenshots I wrote this small … Continue reading →<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[26,36,65,12],"class_list":["post-405","post","type-post","status-publish","format-standard","hentry","category-articles","tag-php","tag-programming","tag-qa","tag-unit-testing"],"_links":{"self":[{"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/posts\/405","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/comments?post=405"}],"version-history":[{"count":1,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/posts\/405\/revisions"}],"predecessor-version":[{"id":406,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/posts\/405\/revisions\/406"}],"wp:attachment":[{"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/media?parent=405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/categories?post=405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scipilot.org\/blog\/wp-json\/wp\/v2\/tags?post=405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}