In Protractor e2e tests, how can I take a screenshot? - continuous-integration

Running protractor, I want to call for a screenshot as part of my spec.
I don't want to take a screenshot every test, and these "reporters" are taking them at every test, every failed test, or once per spec.
This is all very meta, but more importantly I just want a picture to take, and save on a Bamboo CI server.
Where do I start?

I made an npm module for this https://www.npmjs.com/package/screenshot-protractor
Add the module to your project with:
npm install screenshot-protractor --save
In your conf.js file locate or create your onPrepare function.
onPrepare: function() {
}
inside your onPrepare, add this line:
global.screenshot = require('screenshot-protractor').saveScreenshot;
then in the spec.js file, add
screenshot('path/to/screenshots.png');

Use takeScreenshot() and fs module:
var fs = require('fs');
browser.takeScreenshot().then(function (data) {
var stream = fs.createWriteStream('test-results/test.png');
stream.write(new Buffer(data, 'base64'));
stream.end();
});

Related

Can we run one it block from one file and one it block from 2nd file and we have 100s of it block in both files in jasmine protractor

Like in JUnit we have category annotation where we define regression, sanity name and set this category in pom.xml file to run only those Testcases. We dont need to change anything afterwards.
can we do same in Jasmine Protractor???
If we do have one file which is firstfile.ts
describe('angular-material paginator component page', () => {
const EC = protractor.ExpectedConditions;
beforeAll(async() => {
await browser.get('https://material.angular.io/components/paginator/examples');
});
it('Should navigate to next page', async() => {
await $('button[aria-label=\'Next page\']').click();
});
it('Should navigate to previous page', async() => {
await $('button[aria-label=\'Previous page\']').click();
});
it('Should change list length to 5 items per page', async() => {
await $('mat-select>div').click();
});
});
like this we have one more spec file and i want to set categories of the it block so i can write that only one word and run the test like in JUnit.
other than the option of f and x before describe and it block.
For annotation based execution you can try BDD in protractor with cucumber.
Here you can create features which can be organised and executed.
Refer this github repo : https://github.com/igniteram/protractor-cucumber-typescript.git
Please try to clone this repo and understand how it works.

Jasmine UI automation

I have set up my jasmine framework using the steps mentioned here, but when I try to use jasmine keywords like browser.open to open a URL in the Browser I get an error browser not defined. When I use require to get another page, it gives Reference error: module not found.
Also, with my jasmine package, I did not get the specRunner.html.
I have tried installing protractor also and different approaches, but it's not working.
I need to set up jasmine framework for UI automation, can anyone help me with the exact set up and issues that I am facing right now?
The jasmine library is not related to browser automation. It is a library about testing. It does not define the browser object. I'm not sure which library you expect to require. Perhaps you want to use Selenium. In particular, you will want to look at the WebDriver API.
It allows you to do things like this:
var driver = new webdriver.Builder().build();
driver.get('http://www.google.com');
var element = driver.findElement(webdriver.By.name('q'));
element.sendKeys('Cheese!');
element.submit();
driver.getTitle().then(function(title) {
console.log('Page title is: ' + title);
});
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title.toLowerCase().lastIndexOf('cheese!', 0) === 0;
});
}, 3000);
driver.getTitle().then(function(title) {
console.log('Page title is: ' + title);
});
driver.quit();

Webpack and a legacy plugin that takes the real window object as an argument

I am migrating an app from Require.js to Webpack. Among the jQuery plugins that the app uses is hc-sticky. The source file of this plugin starts like this:
(function($, window, undefined) {
"use strict";
// console.log shortcut
var log = function(t){console.log(t)};
var $window = $(window),
document = window.document,
$document = $(document);
// detect IE version
var ie = (function(){var undef, v = 3, div = document.createElement('div'),
The module built with Webpack breaks at the last line of the above fragment, because the window that is passed as an argument to the plugin turns out to be an empty object that doesn't have reference to the document.
Could you please advise how to integrate this plugin in the Webpack build? I searched, but failed to find a working solution. An attempt to substitute this for window:
{test: /jquery-hc-sticky/, loader: 'imports?this=>window'}
doesn't work.

How to reset the Flux stores between jasmine tests?

When running tests on stores with karma & jasmine (instead of jest), the store's state persists between tests. What's the best way to reset the state for every test?
With jest, every test is run in its own environment automatically. This post includes instructions for how to clear the require cache between tests for karma (copied below) to imitate jest, but I can't seem to get it to work.
//tests.webpack.js (suggested by linked article, modified to match my project structure)
// Create a Webpack require context so we can dynamically require our
// project's modules. Exclude test files in this context.
'use strict';
var projectContext = require.context('./path/to/js', true, /^(?!\.test).js$/);
// Extract the module ids that Webpack uses to track modules.
var projectModuleIds = projectContext.keys().map(function (module) {
return String(projectContext.resolve(module));
});
beforeEach(function () {
// Remove our modules from the require cache before each test case.
projectModuleIds.forEach(function (id) {
return delete require.cache[id];
});
});
My current file:
tests.webpack.js (current)
var context = require.context('./path/to/js', true, /\.test\.js$/);
context.keys().forEach(context);
Not sure if it helps, but here's a simplified version of the code from my tests that shows the store's state persisting between tests.
MissionStore.test.js
describe('MissionStore', function() {
beforeEach(function() {
this.MissionStore = rewire("./MissionStore");
this.registeredCallback = this.MissionStore.__get__("registeredCallback");
});
// A bunch of initialization tests without data
describe("set data", function(){
beforeEach(function(){
// Sets this.MissionStore.getMissions() to some sample data
this.registeredCallback(fetchMissions);
});
it('modifies mission data', function(){
var mission = this.MissionStore.getMissions()[0];
expect(mission.edit).not.toEqual(true);
// modify mission to add an edit flag = true
this.registeredCallback({
actionType: MissionConstants.MISSION_TOGGLE_EDIT_FLAG,
mission : mission
});
expect(this.MissionStore.getMissions()[0].edit).toEqual(true);
});
it('do something else', function(){
expect(this.MissionStore.getMissions()[0].edit).not.toEqual(true); // Failing test
console.log(this.MissionStore.getMissions()[0]);
// prints {..., edit: true}
});
});
});
In the 'do something else' test, I'm expecting the this.MissionStore state to be reset between tests so edit won't be equal to true anymore. How would I go about doing this?
Your /^(?!\.test).js$/ RegExp supposed to match every file ending with .js but not with .test.js is wrong, it will only ever match .js. It should be /^(?!.*\.test\.js$).*\.js$/. See Negative lookahead Regular Expression.
So my guess is that projectModuleIds is empty, and that you are not invalidating anything between require calls.

Run multiple specs using jasmine and jstestdriver

I have written multiple spec files for unit testing various modules on the webpage. If i run them individually, one at a time they work fine. But when i try to run all the files in a sequence, only the first file in the spec folder works while all other tests fail. Any help would be appreciated.
Every spec file loads a static page using requirejs and renders them on the page. Once the page is rendered i check whether the title, text etc is proper or not. The spec files looks like this.
AboutSpec.js-->
require(["views/About", "nls/messages"], function (About, messages) {
beforeEach(function(){
var temp = new About();
temp.render();
});
describe("Test for About Page", function () {
it("Check For About Title", function () {
var aboutTitleText = $('.eight.columns h2').text();
expect(aboutTitleText).toEqual(messages["about_title"]);
});
});
});
FooterSpec.js-->
require(["views/Footer", "nls/messages"], function (Footer, messages) {
beforeEach(function(){
var temp = new Footer();
temp.render();
});
describe("Test for Footer Page", function () {
it("Check For Footer Content", function () {
var footerText = $('.five.columns h2').text();
expect(footerText).toEqual(messages["footer_content"]);
});
});
});
jstestDriver.conf-->
load:
- jasmine/lib/jasmine-1.3.1/jasmine.js
- jasmine/lib/adapter/JasmineAdapter.js
- js-src/javaScript/require.js
- js-src/javaScript/default.js
test:
- js-test/AboutSpec.js
- js-test/FooterSpec.js
When i run this setup, the About page does not render. Only the Footer page renders due to which all the test cases of about page fails.
We're facing the exact same problem, and I've spent--how many hours, now? Oh yeah, too many!-- trying to solve this problem.
Today I discovered Karma, a JsTD replacement from Google which runs every test in a fresh iframe. It also integrates with Jenkins. I'm in the process of installing it now and will report back on how it went.

Resources