If you’ve worked with E2E tests for any amount of time, you will have experienced tests that, for whatever reason, randomly fail; aka flakey tests. Such failures can be caused by any number of things: a network glitch, browser barf, app hiccup, act of God, etc….
Test flake can seriously undermine the trust in automation, and drive your automation engineer to drink (or perhaps just drink more). A wise test engineer will embrace that flake happens, and account for it in their automation strategy.
One popular strategy is to re-run failed tests. This way, if a test fails, it gets re-run ‘n‘ number of times, and if it passes, life is good. Enter Protractor-Flake.
Protractor-Flake parses your Protractor test output, looking for failures, and re-runs any failing tests (note: at the spec file level) at the end of your test run. It works really well and is simple to setup. Here’s how…
First install it as a dependency:
1 |
npm install protractor-flake --save |
Then you can run it directly by using it in place of Protractor (note: the ‘–‘ denotes the end of args passed to protractor-flake, and the beginning of args passed to Protractor):
1 |
node_modules/.bin/protractor-flake -- conf.js |
Or you can use it programmatically. I like to create a simple node script, which allows me to add logging and reporting (future blog post). Here’s an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/usr/bin/env node var protractorFlake = require('protractor-flake'); // skip first two args (node and self) var protractorArgs = process.argv.splice(2); protractorFlake({ protractorPath: 'node_modules/.bin/protractor', maxAttempts: 2, parser: 'standard', nodeBin: 'node', protractorArgs: protractorArgs }, function(status, output) { process.exit(status); }); |
Saving the above script as a file, 'flake'
, you could then run your tests thusly:
1 |
./flake conf.js --baseUrl=http://qualityshepherd.com |
Now obviously, you should be killing off flakey tests to the best of your ability, but Protractor-Flake can save you from non-test-related flakiness, and keep your tests green! You can see a working example in my protractor-example repo on GitHub.
Hello,
Great post. I’m using protractor-flake now and running my tests on Codeship tool, but I noticed that codeship is failing even flake running for the second time and passing all the tests. Do you have any solution so that it can be resolved in codeship?
Thanks Rafael! I’m not sure about your codeship issue… we run flake on codeship, so I know it will work. Try your question on StackOverflow. Good luck!
(mail bounced from [email protected])
Hi Brian,
Good day to you, I’ve found your blog while searching for test automation, wow QA since 1999….. :)
I’ve just released the beta version of an open-source web automation tool that is based on CasperJS & PhantomJS. Someone shared to Hacker News and the repo stars jumped from 2 to 1000+ over the weekend.
I’m trying to reach out to experienced QA and test automation folks. May I kindly invite you to take a look if that is something interesting to you or someone you know? I welcome suggestions to make it better!
https://github.com/tebelorg/TA.Gui
FEATURES
– natural language with JavaScript support
– Chrome extension for recording steps
– headless (invisible) and visible mode
– repositories for reusable objects
– datatables for batch automation
– auto-wait for element to interact
– dynamic XPath/CSS element selector
– run by schedule, command line, REST API
– support outgoing API calls to webservices
– cross-platform (macOS/Linux; Windows soon)
Kind Regards,
Ken / Tebel.Automation
Hey Ken,
Thanks for the bug report! I just moved my site to a new server, and forgot to add an mx for ‘info’. Fixed.
Sure, I’ll have a peek. Can’t have too many automation tools! I’m curious about PhantomJS. It’s too much of a pain to use with Protractor, and I just end up testing against chrome, and firefox headlessly anyway (on my own server I call “Otto”, and Codeship CI). Maybe that’s an option with your tool too.
Thanks for pinging me
Hi Brian, I think I missed your reply somehow.
Yeah PhantomJS is a great piece of work, but can be tricky as it kinda lags behind newer web standards. And it is not exactly sure if there will be a new maintainer. I hope the project will continue!
I recently integrated with headless Chrome. But there are many new tools to do that which are more appropriate for test automation (imo), and you might have already seen this list.
https://medium.com/@kensoh/chromeless-chrominator-chromy-navalia-lambdium-ghostjs-autogcd-ef34bcd26907
I have downloaded and executed the files that you have placed in git for reference.. Execution is successful .
I have forced one of the ‘it’ to fail . How to rerun the failed test scripts or specs .
Downloaded and extracted the git zip file and just provided npm update in the project path and started running the file using protractor conf.js. Where the concept flake comes here to help me to rerun.
I have edited flake file and added path as ‘My project path where conf.js’ is located or I need to give path where protractor is actually installed in my machine
protractorFlake({
protractorPath: ‘C:\Users\mythilisri\Downloads\protractor-example-master\protractor-example-master’,
maxAttempts: 2,
parser: ‘standard’,
nodeBin: ‘node’,
protractorArgs: protractorArgs
}, (status, output) => {
process.exit(status);
});
I intentionally failed one test case by marking ‘expect’ as ‘false’ . This is shown in console as one test case fail out of 15
Then how would able to run this failed test script
my project structure is
— Protractor Example
—–node-modules
—–data
—–pages
—-Specs
—-flake
—-conf.js
—package.json
Output:
C:\Users\XXXXXXXX\Documents\protractor-example-master\protractor-example-master>protractor conf.js
[07:21:39] I/launcher – Running 1 instances of WebDriver
[07:21:39] I/direct – Using ChromeDriver directly…
Spec started
angular app
x should add a new friend
– Expected true to be false.
√ should delete an existing friend
√ should not display non-found search terms
√ should display found search terms
√ should display no rows when all friends deleted
√ should display actual count before saving new friend
non-angular login
√ should display message for invalid credentials
√ should display message for empty credentials
√ should goto friend pages on successful login
Quality Shepherd blog
√ should display 5 posts per page
√ should return search results
√ unfound search term should return no results
switching to window 1
switching to window 0
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
x should open social media link in new window
– Error: Timeout – Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
√ sidebar should have a set width
√ should find an older post by paging
**************************************************
* Failures *
**************************************************
1) angular app should add a new friend
– Expected true to be false.
2) Quality Shepherd blog should open social media link in new window
– Error: Timeout – Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Executed 15 of 15 specs (2 FAILED) in 1 min 53 secs.
[07:23:36] I/launcher – 0 instance(s) of WebDriver still running
[07:23:36] I/launcher – chrome #01 failed 2 test(s)
[07:23:36] I/launcher – overall: 2 failed spec(s)
[07:23:36] E/launcher – Process exited with error code 1
How can I run my failed test scripts . Please help me on this
Hey Sridhar,
You need to run the tests with
protractor-flake
, instead of justprotractor
. Eg../flake conf.js
you mean
C:\Users\XXXXXXXX\Documents\protractor-example-master\protractor-example-master>protractor-flake conf.js
or C:\Users\XXXXXXXX\Documents\protractor-example-master\protractor-example-master>./flake conf.js
both throws error .
Method A : protractor-flake –parser multi –max-attempts=2 — regressionJobConf.js
Method B :
protractor-flake –./flake — regressionJobConf.js
I am able to run test with Method A.
but “Method B” is failing. please help for method B.
Hi Brine,
Is my way of execution is wrong ?. Please correct me
Hi Brine,
Working fine > Thanks
All specs are running on failure I need only failed spec to be re-run. Please guide me Brine…..
Yeah, this is because
protractor-flake
parses the stack traces to match failing tests. It’s not grabbing the stack trace from the standard output for some reason. I just pushed some changes to my example code that switch flake to parse"multi"
(instead ofstandard
), and protractor to shard tests. This is how I normally run, and it will now only run the failed tests. To get this to work via non-sharded tests, you’d have to fixprotractor-flake
‘s parse matcher to suit your needs.https://www.pcloudy.com/5-reasons-why-pcloudy-is-the-simplest-app-testing-platform/
sry
run with flake ./flake conf.js
I am not able to Run this file with the above command, it throws me error:
‘.’ is not recognized as an internal or external command,
operable program or batch file.
I am Running your Code(protractor-example) in Windows Machine. I am sensing I am missing something basic. Please help me out.
Hey.. try installing protractor-flake globally (look at my post below)
Ok I solved the issue. It seems that the flake is node script and you need to run the same with node command. So the running the File with like this: node ./flake conf.js resolved my issue.
Hi…
I was looking for a way to rerun my failed tests and found a reference to protractor-flake somewhere. So I followed the steps described here (I am developing on windows environment, using protractor-cucumber-framework). When running >protractor-flake — xxx.conf I was getting “‘protractor-flake’ is not recognized as an internal or external command, operable program or batch file”
So I just tried installing protractor-flake globally (npm i protractor-flake -g) and that solved the problem…
Just in case someone is having the same issue
Hi, Im using Protractor with Typescript. When using protractor-flake and using below command:
node node_modules/protractor-flake/bin/protractor-flake –parser standard –max-attempts=2 — conf.js –suite=regression –browser=chrome –baseUrl=cert –multiCapabilities
after first attempt, I’m see the list of failed tests with extension *_spec.ts. So tests are failing since its not js files. What I should to make a change to rerun the *spec.js files instead *spec.ts files.
Using standard to parse output
Re-running tests: test attempt 2
Re-running the following test files:
C:\01_Projects\Dev\TestAutomation\sample3_spec.ts
C:\01_Projects\Dev\TestAutomation\sapmle5_spec.ts
C:\01_Projects\Dev\TestAutomation\sapmle4_spec.ts
Please let me know how to resolve the issue.
I fixed this by creating a custom parser for Protractor-flake (or changed the existing standard one).
In the case as described above the only thing that needs to be changed is:
failedSpecs.add(match[1].replace(‘.ts’, ‘.js’));
You can add more replaces to fit your needs, for example:
failedSpecs.add(match[1].replace(“specs”, “tmp\\specs”).replace(‘.ts’, ‘.js’));
Hope this helps someone
Hi Brian,
I am using protractor-cucumber-typescript framework. I need to rerun failed test cases.I was install protractor-flake locally and globally. I created protractor-flake.js file. but i am not getting this issues please can you elaborated.
HI,
I am trying to pass environment variable in the command but its not working below is the command used can you please help if i am missing anything.
node ./node_modules/protractor-flake/bin/protractor-flake –params.environment=pp — conf.js
Thanks in-advance
I am able to re-run the failed tests using protractor-flake. The issue I am facing is the reports and logs only show up for the last attempt. I would like to see the complete report of all tests executed from all re-run attempts.
I have tried below reporting tools
‘jasmine-spec-reporter’
‘protractor-jasmine2-html-reporter’
‘jasmine-reporters’
Thanks in advance!!
I fixed this by creating a custom parser for Protractor-flake (or changed the existing standard one).
In the case as described above the only thing that needs to be changed is:
failedSpecs.add(match[1].replace(‘.ts’, ‘.js’));
You can add more replaces to fit your needs, for example:
failedSpecs.add(match[1].replace(“specs”, “tmp\\specs”).replace(‘.ts’, ‘.js’));
Hope this helps someone