All available hooks in protractor - protractor

Is there any link which provides information on all available hooks in protractor.
For Instance, in webdriverIO we have the below :
onPrepare: function (config, capabilities) {},
beforeSession: function (config, capabilities, specs) {},
before: function (capabilities, specs) {},
beforeSuite: function (suite) {},
beforeHook: function () {},
afterHook: function () {},
beforeTest: function (test) {},
beforeCommand: function (commandName, args) {},
afterCommand: function (commandName, args, result, error) {},
afterTest: function (test) {},
afterSuite: function (suite) {},
after: function (result, capabilities, specs) {},
afterSession: function (config, capabilities, specs) {},
onComplete: function (exitCode, config, capabilities, results) {},
onReload: function(oldSessionId, newSessionId) {},
I am looking for similar hooks in protractor.

I can't ensure these are 100% comprehensive but this is something I generated a while ago. Protractor and Jasmine hooks in the order they run.
--- beforeLaunch
--- onPrepare
--- jasmineStarted (set in jasmine reporter)
--- beforeAll
--- suiteStarted (set in jasmine reporter)
--- specStarted (set in jasmine reporter)
--- beforeEach
+++ afterEach
+++ specDone (set in jasmine reporter)
+++ suiteDone (set in jasmine reporter)
+++ afterAll
+++ jasmineDone (set in jasmine reporter)
+++ onComplete
+++ afterLaunch
If there are further hooks I have missed I would also appreciate someone pointing them out to here.
You can read more about Protractor hooks here and more about the Jasmine hooks here
Additional code based on comment
onComplete: function (passed) {
if (!passed) {
request({
uri: https: '//${browserstack.user}:${browserstack.key}#api.browserstack.com/automate/sessions/${ browser.sessionId }.json', method: 'PUT', form: { status: 'error' },
});
}
}

Protractor is just a wrapper for selenium-webdriver so they don't have any hooks. I suspect you are looking using a framework to drive your tests like jamsmine or cucumber so you will need to use their hooks. Think of it like Protractor being the car and jasmine being the driver telling the car what to do and when to do it.
There is 1 hook(not really a hook but similar) that you can use and that is the onPrepare in the protractor config file.

Related

How to perform beforeTest and afterTest method using typescript (protractor+cucumber)

Framework used - Protractor
BDD - Cucumber
Language - Typescript
Now i have implemented the framework and a test scenario is also running fine with protractor.
But the problem i am facing is when i write another cucumber scenario my test fails saying 'A session is either terminated or not started'
The above failure is because when my first cucumber scenario starts the appium server starts with in my config and at the end i close the server/driver
Now i have written another test scenario, since cucumber is independent of each scenario , when the sec starts it does not do the config again. Now i need a beforeTest method to call.
So i am not sure how to implement that in typescript,as i am new to it.
Tried the same concept of java way but not working out. There where examples for javascript but still did not help me out.
Tried creating a new util folder and placing my beforeTest inside that but the function is not calling there
Tried to use beforeLaunch()with in my config file, but still does not work out
my config file: config.ts
export let config: Config = {
allScriptsTimeout: 40000,
getPageTimeout: 40000,
setDefaultTimeout: 60000,
defaultTimeoutInterval: 30000,
specs: [
// '../../utils/beforeEach.ts',
'../../features/*.feature',
],
onPrepare: () => {
Reporter.createDirectory(jsonReports);
tsNode.register({
project: './tsconfig.json'
});
},
multiCapabilities: [
androidPixel2XLCapability,
// iPhoneXCapability
],
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
cucumberOpts: {
compiler: "ts:ts-node/register",
glue: ["steps"],
format: [
"json:./reports/json/cucumber_report.json",
],
require: ['supports/timeout.js', '../../stepdefinitions/*.ts'],
tags: "#firstPurchasePopup",
},
seleniumAddress: serverAddress,
onComplete: () => {
Reporter.createHTMLReport();
},
// =====
// Hooks
// =====
beforeTest: function () {
},
beforeLaunch(){
console.log("Before");
seleniumAddress: 'http://localhost:4723/wd/hub';
},
afterLaunch() {
console.log("After");
},
};
my other beforeEach.ts:
This is not working but what i tired and was not working.
import {After, AfterAll, Before} from "cucumber";
const serverAddress = 'http://localhost:4723/wd/hub';
import {beforeEach, afterEach, describe} from "selenium-webdriver/testing";
beforeEach(function () {
console.log("Before");
});
// });
afterEach(function () {
console.log("Before");
});
// let beforeEach: () => void;
// beforeEach = () => {
// console.log("Before Test");
// // config.multiCapabilities;
// seleniumAddress: serverAddress;
// };
//
// let afterEach: () => void;
// afterEach = () => {
// console.log("After Test");
// };
This is my feature file: bonus.feature
this is my feature file:
Background:
Given I launch the app
Then I should see the popup window for the Bonus
And I verify the UI
Then I tap on ok button
And The popup window should not be seen
#firstPurchasePopup
Scenario: firstPurchasePopup new join button
When I tap on the 'New ' button
And The popup window should not be seen
Then I navigate back from join page to home page
Then The popup window should not be seen
Then I close the app
#firstPurchasePopup
Scenario: firstPurchasePopup login button
And I tap on log in button on the initial screen
Then I navigate back from login page to home page
And The popup window should not be seen
Then I close the app
I expect my the scenario what i have written to execute both one after the other , like execute Scenario: firstPurchasePopup new join button which it does . But when it launches the app again for the sec Scenario: firstPurchasePopup login button does not work as the driver is not started again, since it was closed in prev one.
to start it i need to create beforeTest which i am facing difficutly to write the code
I haven't used Protractor with Cucumber, but I have used Cucumber & Typescript together. I resolved the problem by having a file cucumber.js in a root that is being loaded at the very beginning by default and looks like that:
var settings = "features/**/*.feature -r step-definitions/**/*.ts -r hooks/**/*.ts -r support/**/*.ts "
module.exports = {
"default": settings
}
However, I think in your case the solution would be adding a path to hooks file to config.cucumberOpts.require list instead to config.specs one.
Did you try it?
#All
Thanks for your inputs #mhyphenated
I figured out that the rather than using inside the config, i tried using the before and after in the hooks.ts ,also other than calling the server i was not actually calling the android driver, as below and that worked
beforeTest: function () {
beforeTest: function () {
},
beforeLaunch(){
console.log("Before");
seleniumAddress: 'http://localhost:4723/wd/hub';
},
hooks.ts
import { AndroidDriver } from "appium/node_modules/appium-android-driver";
let driver:AndroidDriver, defaultCaps;
driver = new AndroidDriver();
Before(function () {
// This hook will be executed before all scenarios
browser.ignoreSynchronization = false;
browser.manage().timeouts().implicitlyWait(500);
let defaultCaps = config.multiCapabilities[0];
console.log("defaultCaps = ", defaultCaps );
driver.createSession(defaultCaps);
driver.defaultWebviewName();
});

As soon as protractor execute first it block gives an error :-Error while waiting for Protractor to sync with the page

describe('Login Scenarios', function () {
it('First IT block', function () {
browser.get('http:XXXXXXXXXXXXXXXXXXXX');
browser.manage().window().maximize();
LoginPage.Login(USERNAME, PASSWORD);
});
it('Second IT block', function () {
browser.waitForAngularEnabled(false);
Properties.logout.click();
Properties.confirmlogout.click();
AutomationUtility.hold();
});
});
When I keep all the code in first IT block it runs fine but when divided into multiple test cases protractor will execute first IT block only, after that it gives an error message as:-
Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details
Then, Protractor does not close the browser and gives the error messages of not finding element etc as protractor running test cases in chronological order.
Move browser.waitForAngularEnabled(false); to configuration protractor.conf.js file into onPrepare section.
export let config = {
...
...
onPrepare () => {
browser.waitForAngularEnabled(false);
...
},
...
...
};
Or disable wait for angular before browser.get(), then enable after browser.get()
describe('Login Scenarios', function () {
it('First IT block', function () {
// disable if opening page is non-angular page
browser.waitForAngularEnabled(false);
browser.get('http:XXXXXXXXXXXXXXXXXXXX');
// revert back to enable, after the non-angular page opened.
browser.waitForAngularEnabled(true);
browser.manage().window().maximize();
LoginPage.Login(USERNAME, PASSWORD);
});
it('Second IT block', function () {
Properties.logout.click();
Properties.confirmlogout.click();
AutomationUtility.hold();
});
});
I am able to resolve by putting URL in onPrepare section. In to configuration protractor.conf.js file:-
return browser.get('http://XXXXXXXXXXXXXXXXXXXX/login');
Thus the protractor is not failing when clicked on the login button. Also not getting any Error while waiting for Protractor to sync with the page.

ScriptTimeoutError: Timed out - From: Task: Protractor.waitForAngular()

I am trying to run basic end to end tests written using protractor. I always get this error.
ScriptTimeoutError: Timed out
I checked this link https://github.com/angular/protractor/blob/master/docs/timeouts.md and increased the default timeout, but still I get the same error. I am not able to figure out from where this error pops out. The browser loads the base Url, later it will not perform any action as mentioned in the test. The test is very simple , open the browser and click on the menu and verify if the URL is matched.
Node Version: v7.5.0
Protractor Version: 5.1.2
Angular Version: 2.4.10
Browser(s): firefox
Operating System and Version ubuntu
typescript: 2.2.2
Config file
exports.config = {
framework: 'jasmine2',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['test/e2e/menu.js'],
capabilities: {
'browserName': 'firefox',
},
baseUrl: 'http://localhost:8100/#/',
//allScriptsTimeout: 360000,
jasmineNodeOpts: {
showColors: true,
// defaultTimeoutInterval: 360000
},
//useAllAngular2AppRoots:true,
//menu.js
describe('menu check', function () {
beforeEach(function () {
browser.get('http://localhost:8100/#/');
browser.waitForAngular();
// browser.driver.manage().timeouts().setScriptTimeout(60000);
});
it('Should route to the operationalView page from menu', function () {
element(by.css('[href="#/operationalView"]')).click();
expect(browser.getCurrentUrl()).toMatch('http://localhost:8100/#/operationalView');
});
it('Should route to the worldlview page from menu', function () {
element(by.css('[href="#/worldView"]')).click();
expect(browser.getCurrentUrl()).toMatch('http://localhost:8100/#/worldView');
});
});
I have had this issue once, which I resolved using
browser.ignoreSynchronization=true
before the beforeEach() method in your Protractor spec files. This makes Protractor not wait for Angular promises, such as those from $http or $timeout to resolve. You can try this in your script.
Edit : As of today, 08/16/19, this solution has been deprecated. Use waitForAngularEnabled to be false instead.

Webpack / Babel / Karma does not complain if test files are invalid

How do I make webpack and karma fail on babel transpiling errors?
Pretty standard setup loading test files like so:
var context = require.context('./app', true, /\.test\.js$/);
context.keys().forEach(context);
Given I have these two test:
describe('Success', () => {
it('should pass', () => {
expect(true).toEqual(true)
});
});
and
describe('Failure', () => {
it('should fail', () => {
expect(true).toEqual(false)
});
});
Then all works well:
Suites and tests results:
- Failure :
* should fail : failed
- Success :
* should pass : ok
Browser results:
- PhantomJS 1.9.8: 2 tests
- 1 ok, 1 failed
BUT if I invalidate the failing test (removing the closing brackets from the Describe call):
describe('Failure', () => {
it('should fail', () => {
expect(true).toEqual(false)
});
Then rather than getting a break I just get:
Suites and tests results:
- Success :
* should pass : ok
Browser results:
- PhantomJS 1.9.8: 1 tests
- ok
It's like the whole test file didn't exist. This is really problematic as with a large test suite an accidental keystroke in a random test file can cause the whole test to be ignored and a possibly failing build to succeed.
I tried configuring the setting the bail option to true in my karma.config:
webpack: {
bail:true,
But made no difference.
How do I make webpack and karma fail on babel transpiling errors?

Selective test execution in Karma Jasmine using pattern matching

I'm having trouble invoking the command line option on karma-jasmine which allows for the execution of only those tests which match a given pattern. My spec reads as follows:
/path/to/single-test/main.spec.js
describe('my first test suite', function() {
it('always passes', function() {
expect(true).toBe(true);
});
it('still always passes', function() {
expect(true).toBe(true);
});
});
I'm assuming the description (for example "still always passes") is the item against which the pattern specified by the grep command line option is matched. When I attempt to run the second example based on the fact that its description is the only example containing the word "still", both examples are executed instead of just the one:
$ karma start -- --grep=still
INFO [karma]: Karma v0.12.35 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket 7Dn7Ez1Reap7ch0Uzsb0 with id 44623726
PhantomJS 1.9.8 (Linux 0.0.0): Executed 2 of 2 SUCCESS (0.002 secs / 0.001 secs)
How do I execute just this one example based on a pattern? The official documentation doesn't give a sample of the usage of the pattern matching option.
I read in the discussion of a pull request, that the grep option can be used in conjunction with "fit" and "fdescribe." This works when tested. However, in the case of using grep with "fit", what's the purpose of the pattern argument to the grep option? (It would be nice to be able to execute tests selectively without the need to augment source code!)
Here is the remainder of the files in my project for reference:
/path/to/single-test/karma.conf.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: ['*.spec.js'],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true
});
};
/path/to/single-test/package.json
{
"name": "single-test",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"devDependencies": {
"jasmine-core": "^2.3.4",
"karma": "^0.12.35",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.2.0",
"phantomjs": "^1.9.17"
}
}
You have to start a Karma server, then specify the --grep option in a Karma runner. I.e. something along the lines of:
karma start path/to/karma.conf.js
Then in another terminal:
karma run path/to/karma.conf.js -- --grep=still
It is important that you set singleRun: false in the configuration options.
There is karma-jasmine-spec-tags plugin which helps to filter running tests by tags in their names.
Example usage:
$ karma start --tags smoke
$ karma start --skip-tags slow,bench
$ karma start --tags bench --skip-tags slow
$ karma start --tag-prefix 'scope:' --tags critical
Where a spec is following:
describe('Example test', () => {
it('should be a #smoke test', () => {
// ...
});
it('#slow test', () => {
// ...
});
})
describe('Performance test suite #bench', () => {
it('#fast #smoke test', () => {
// ...
});
it('#slow test', () => {
// ...
});
})
describe('Custom tag prefix', () => {
it('test scope:critical', () => {
// ...
});
})