ngMockE2E does not work with remote Selenium server - angularjs

Setup
We use protractor, protractor-cucumber, and angular-mocks to handle our e2e tests. Builds are managed by grunt.
We have two build configs; pool and local. pool is the configuration that is picked up by our CI environment, local is for debugging purposes and is setup to run on a local machine. The primary difference between the two setups is that local runs everything locally, whereas pool uses a remote Selenium server (outside the CI server itself).
protractor.conf.js:
exports.config = {
params: {
widgetUrl: 'http://localhost:9980',
vudUrl: 'xxx',
testDelay: 3000,
},
// The timeout for each script run on the browser. This should be longer
// than the maximum time your application needs to stabilize between tasks.
allScriptsTimeout: 150000,
// A base URL for your application under test. Calls to protractor.get()
// with relative paths will be prepended with this.
baseUrl: 'http://localhost:' + (process.env.PORT || '9082'),
// list of files / patterns to load in the browser
specs: ['./e2e/features/*.feature'],
cucumberOpts: {
require: ['./e2e/steps/*.js', './e2e/pageObjects/*.js', './e2e/support/*.js'],
format: 'pretty',
tags: ['#context-test']
},
// Patterns to exclude.
exclude: [],
// ----- Capabilities to be passed to the webdriver instance ----
//
// For a full list of available capabilities, see
// https://code.google.com/p/selenium/wiki/DesiredCapabilities
// and
// https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
capabilities: {
browserName: 'chrome',
loggingPrefs: {
'driver': 'INFO',
'server': 'INFO',
'browser': 'INFO'
}
},
// ----- The test framework -----
//
// Jasmine and Cucumber are fully supported as a test and assertion framework.
// Mocha has limited beta support. You will need to include your own
// assertion framework if working with mocha.
framework: 'custom',
frameworkPath: 'node_modules/protractor-cucumber-framework',
mocks: {
dir: "mocks", // path to directory with mocks
default: []
},
onPrepare: function() {
// Chai config
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
global.expect = chai.expect;
console.log('params: ' + JSON.stringify(browser.params));
//browser.driver.manage().window().maximize();
}
};
We configure our mocks in a Before hook (snipped here for brevity):
this.Before(function(scenario, callback) {
// ...
let data = require(`${TEST_DATA_DIR}/default.js`);
let httpMocker = function() {
angular.module('httpMocker', ['ngMockE2E'])
.run(function($httpBackend) {
$httpBackend.whenPOST(...);
};
browser.addMockModule('httpMocker', httpMocker, {data})
// ...
callback();
});
Problem
Despite identical test setups, ngMockE2E is not being called when run in the CI environment. This can be demonstrated by the following test:
test.feature:
#Test
Feature: Test and debug
#context-test
Scenario: Get console output
Given I access the page
Then I get the log output
test.steps.js
module.exports = function() {
this.Given(/^I access the page$/, () => {
util.waitAndDo(() => true);
});
this.Then(/^I get the log output$/, () => {
util.waitAndDo(() => {
browser.manage().logs().get('browser').then(function(browserLog) {
console.log('log: ' + require('util').inspect(browserLog));
});
})
});
};
This test will dump the browser log rather than actually testing anything. When it is run locally, the logs are empty. However, when the same test is run in the CI environment, the logs show errors for failed calls to the URLs being mocked.
We have verified that the URLs used in the CI environment correctly match the regex in our mocks, so it is not a match-miss. The module is simply not being called.
To reiterate - the only major difference in configuration is that the pool config makes use of a remote Selenium hub. How could this affect how our tests are run, and why would it prevent our mocks from working?

Related

How to cache React application in service worker

I'm trying to create a React PWA from scratch. So far my project outputs the minified files to a dist/js folder.
In my service worker file I'm using Workbox to precache the app. This is my setting so far:
importScripts("./node_modules/workbox-sw/build/workbox-sw.js");
const staticAssets = [
"./",
"./images/favicon.png",
]
workbox.precaching.precacheAndRoute(staticAssets);
Currently if I enable offline from dev tools > Service Workers, it throws these errors and the app fails to load:
3localhost/:18 GET http://localhost:8080/js/app.min.js net::ERR_INTERNET_DISCONNECTED
localhost/:1 GET http://localhost:8080/manifest.json net::ERR_INTERNET_DISCONNECTED
3:8080/manifest.json:1 GET http://localhost:8080/manifest.json net::ERR_INTERNET_DISCONNECTED
logger.mjs:44 workbox Precaching 0 files. 2 files are already cached.
5:8080/manifest.json:1 GET http://localhost:8080/manifest.json net::ERR_INTERNET_DISCONNECTED
How can I fix this?
this means your resources are not getting cached properly,
you need to add them to cache before accessing,
workbox by default do it for you.
it shows 2 files cached, as they present in your array, expected result
same do it for all remaining too.
const staticAssets = [
"./",
"./images/favicon.png",
"./js/app.min.js",
"./manifest.json",
{ url: '/index.html', revision: '383676' }
]
you can try to add eventlistener,
self.addEventListener('install', event => {
console.log('Attempting to install service worker and cache static assets');
event.waitUntil(
caches.open("staticCacheName")
.then(cache => {
return cache.addAll(staticAssets);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request)
.then(function(response) {
if (response) {
return response;
}
return fetch(event.request);
})
);
});

e2e testin with jasmine protractor "no specs found"

I'm new testing with protractor, but I cant run my tests.
My protractor.config.js:
exports.config = {
allScriptsTimeout: 99999,
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
browserName: 'chrome'
},
baseUrl: 'http://localhost:8080/',
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['.src/test/e2e/login.e2e.spec.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
isVerbose: true,
includeStackTrace: true
}
};
and this is the test I'm trying to run:
'use strict';
describe('my app', function() {
beforeEach(function () {
browser.get('index.html');
});
it('should automatically redirect to / when location hash is empty', function() {
expect(browser.getLocationAbsUrl()).toMatch("/");
});
});
And this is the error I get:
I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[13:20:49] I/launcher - Running 1 instances of WebDriver
Started
No specs found
Finished in 0.001 seconds
[13:20:50] I/launcher - 0 instance(s) of WebDriver still running
[13:20:50] I/launcher - chrome #01 passed
[13:20:50] The following tasks did not complete: e2e
[13:20:50] Did you forget to signal async completion?
I'm running webdriver-manager and my app server. My jasmine version is: 2.5.2
and my protractor version is:
4.0.9
Any idea of what I'm doing wrong??
Thanks!!!
I realized what was my problem (thanks to the comments that helped me to realize).
I was running my test with a gulp task I made:
function e2e() {
gulp.src(["/src/test/*.js"]).pipe(protractor({
configFile: "conf/protractor.config.js",
args: ['--baseUrl', 'http://localhost8080']
})).on('error', function (e) {
throw e;
});
}
I dont know why this: gulp.src(["/src/test/*.js"])wasnt getting to acces to my test files, so I changed it for: gulp.src(["src/test/e2e/login.e2e.spec.js"])
I know its not the best solution,but enough to survive...

Why I get this error in Protractor of Jasmine timeout and how can i test correctly?

I posted an issue because I thought it was a bug with something to do with Jasmine.
Here is link: https://github.com/angular/protractor/issues/3130#event-628418439
I try to run a simple request to the server. The server reply and angular shows the message but the test freezes and i get the error below.
I am new in e2e (testing in general). Am I doing something wrong or it is a bug.
protractor protractor-e2e.js
Starting selenium standalone server...
[launcher] Running 1 instances of WebDriver
Selenium standalone server started at http://192.168.0.115:54697/wd/hub
Started
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
F
Failures:
1) Registration view should ask for a proper email "The email must be a valid email address."
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at tryOnTimeout (timers.js:224:11)
at Timer.listOnTimeout (timers.js:198:5)
Ran 1 of 9 specs
1 spec, 1 failure
Finished in 27.718 seconds
Shutting down selenium standalone server.
[launcher] 0 instance(s) of WebDriver still running
[launcher] chrome #01 failed 1 test(s)
[launcher] overall: 1 failed spec(s)
[launcher] Process exited with error code 1
```
protractor --version
Version 3.2.2
==UPDATE : complete test ==
'use strict';
var fulanito = {
name: 'Fulano',
last_name: 'De Tal',
email: 'fulanitodetal2#fulandolandia.com.mx',
password: 'lacontraseñadefulanito',
};
describe('Registration view', function() {
beforeEach(function() {
browser.get('#/account/register');
browser.manage().logs().get('browser').then(function(browserLog) {
console.log('log: ' + require('util').inspect(browserLog));
});
});
fit('should aske for a proper email "The email must be a valid email address."', function function_name(argument) {
var inputname = element(by.model('userData.name')).sendKeys(fulanito.name);
var inputname = element(by.model('userData.last_name')).sendKeys(fulanito.last_name);
var inputemail = element(by.model('userData.email')).sendKeys('fulanito#ara');
var inputpassword = element(by.model('userData.password')).sendKeys(fulanito.password);
var inputpassword_confirmation = element(by.model('userData.password_confirmation')).sendKeys(fulanito.password);
});
it('should see "Registro"', function() {
expect(element(by.css('h1')).getText()).toContain('Registro');
});
My config file
exports.config = {
allScriptsTimeout: 99999,
// The address of a running selenium server.
//seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
onPrepare: function() {
// you can also add properties to globals here
global.host= 'http://localhost:9000/';
},
keepAlive: true, //intesive testing
baseUrl: 'http://localhost:9000',
//Stand alone: 9001
//baseUrl: 'http://localhost:9001',
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
//specs: ['test/e2e/*.js'],
specs: ['test/e2e/register-spec.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 25000,
isVerbose: true,
includeStackTrace: true
}
};
It turns out that there is an error in my code and possible a bug.
fit('should aske for a proper email "The email must be a valid email address."', function function_name(argument) {
var inputname = element(by.model('userData.name')).sendKeys(fulanito.name);
var inputname = element(by.model('userData.last_name')).sendKeys(fulanito.last_name);
var inputemail = element(by.model('userData.email')).sendKeys('fulanito#ara');
var inputpassword = element(by.model('userData.password')).sendKeys(fulanito.password);
var inputpassword_confirmation = element(by.model('userData.password_confirmation')).sendKeys(fulanito.password);
});
The stupid error is that I used the autocomplete for function: function function_name(argument) {} and that causes the error. So one must put : function () {} without the argument. : |
Just to clarify, this argument is designed to be a done function/callback. If you specify it, you have to call it manually when the test is finished. If you don't call it, the test would freeze until a jasmine global timeout is reached. This is exactly what is happening in this case.

protractor "ERROR - Unable to start a WebDriver session"

I have some it tests on my single-page-app written in angular.
the tests are in protractor.
they ran during the build before, but now that I moved all of them to a branch something got broken and when I run the tests I'm getting:
Running "protractor:normal" (protractor) task
Starting selenium standalone server...
[launcher] Running 1 instances of WebDriver
Selenium standalone server started at http://172.31.9.226:23730/wd/hub
ERROR - Unable to start a WebDriver session.
c:\projects\blog-manager\node_modules\protractor\node_modules\selenium- webdriver\lib\atoms\error.js:113
var template = new Error(this.message);
^
Warning: Protractor test(s) failed. Exit code: 1 Use --force to continue.
Aborted due to warnings.
Process finished with exit code 6
the conf file is as follows:
'use strict';
module.exports.config = {
allScriptsTimeout: 60000,
baseUrl: 'http://localhost:9000/',
specs: [
process.cwd() + '/test/spec/e2e/**/*.js'//,
// process.cwd() + '/test/e2e/spec/**/*.js'
],
framework: 'jasmine',
capabilities: {
browserName: 'chrome',
"chromeOptions": {
binary: "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
args: [],
extensions: [],
}
},
onPrepare: function () {
// Disable animations so e2e tests run more quickly
var disableNgAnimate = function () {
angular.module('disableNgAnimate', []).run(function ($animate) {
$animate.enabled(false);
});
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
// Store the name of the browser that's currently being used.
browser.getCapabilities().then(function (caps) {
browser.params.browser = caps.get('browserName');
});
},
jasmineNodeOpts: {
defaultTimeoutInterval: 300000
}
};
any suggestions on how to solve this would be much appreciated.
Thanks!
According to alecxe's answer it's chrome binary issue which can be solved by installing chrome in same place as chromedriver expects to be or specifying the executable path to the binary settings.
capabilities: {
"browserName": "chrome",
"chromeOptions": {
binary: "D:/Program Files/Chrome/chrome.exe",
args: [],
extensions: [],
}
},
See his answer here
Even though you are setting the executable path correctly it seems little off to me binary: "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
Is this correct?
Alternatively, I would try this

Protractor - Cucumber : Annoying ECONNREFUSED Errors while working as expected

I'm trying to integrate Cucumber with protractor, While the setup is working as expected (the test fail and succeed normally), I'm getting annoying ECONNREFUSED errors that makes my feedback unreadable.
Question 1: What't ECONNREFUSED's error exact meaning? I don't really understand the feedback and I couldn't find good documentation for it.
Question 2: What could be the problem with my setup? Is my setup proper?
Question 3: Has anyone run BDD tests in vagrant box with cucumber over protractor? Example code please :)
Dependencies
npm i protractor cucumber selenium-webdriver chai chai-as-promised express grunt-protractor-runner protractor-cucumber --save-dev
As you see I'm running my commands via grunt inside a vagrant box. The vagrant box has only firefox, I'm not sure if that's a problem, protractor was running just fine before.
Terminal Feedback
[vagrant#vagrant web-src]$ grunt protractor:singlerun
Running "protractor:singlerun" (protractor) task
Using the selenium server at http://localhost:4444/wd/hub
Feature: Blog
As a user
I want to visit blog
So that I can stay informed about a topic
Scenario: A disclaimer scenario # tests/e2e/cucumber/features/Blog.feature:6
/var/www/miyagi/web-src/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:131
var session = webdriver.promise.controlFlow().execute(function() {
^
Error: ECONNREFUSED connect ECONNREFUSED
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
==== async task ====
WebDriver.createSession()
at Function.webdriver.WebDriver.acquireSession_ (/var/www/miyagi/web-src/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:131:49)
at Function.webdriver.WebDriver.createSession (/var/www/miyagi/web-src/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:111:30)
at Builder.build (/var/www/miyagi/web-src/node_modules/protractor/node_modules/selenium-webdriver/builder.js:106:20)
at HostedDriverProvider.getDriver (/var/www/miyagi/web-src/node_modules/protractor/lib/driverProviders/hosted.js:63:9)
at /var/www/miyagi/web-src/node_modules/protractor/lib/runner.js:241:41
at _fulfilled (/var/www/miyagi/web-src/node_modules/protractor/node_modules/q/q.js:797:54)
at self.promiseDispatch.done (/var/www/miyagi/web-src/node_modules/protractor/node_modules/q/q.js:826:30)
at Promise.promise.promiseDispatch (/var/www/miyagi/web-src/node_modules/protractor/node_modules/q/q.js:759:13)
at /var/www/miyagi/web-src/node_modules/protractor/node_modules/q/q.js:573:44
>>
>> Test failed but keep the grunt process alive.
Done, without errors.
[vagrant#vagrant web-src]$
Protractor Config
// conf.js
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['../cucumber/features/*.feature'],
multiCapabilities: [{
browserName: 'firefox'
}],
onPrepare: function() {
var width = 1024;
var height = 600;
browser.driver.manage().window().setSize(width, height);
// implicit and page load timeouts
browser.manage().timeouts().pageLoadTimeout(40000);
browser.manage().timeouts().implicitlyWait(25000);
// for non-angular page
browser.ignoreSynchronization = true;
},
framework: 'cucumber',
cucumberOpts: {
require: '../cucumber/features/*.steps.js',
format: 'pretty'
}
};
Grunt task
protractor: {
options: {
configFile: '<%=tests %>/e2e/protractor/config.js', // Default config file
noColor: false, // If true, protractor will not use colors in its output
keepAlive: true
},
auto : {
keepAlive: true // If false, the grunt process stops when the test fails.
},
singlerun: {}
},
Feature
Feature: Blog
As a user
I want to visit blog
So that I can stay informed about a topic
Scenario: A disclaimer scenario
Given I visit blog
Then I should see a disclaimer
Steps
//http://chaijs.com/
var chai = require('chai');
//https://github.com/domenic/chai-as-promised/
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
module.exports = function() {
var url = 'http://dev.com/search',
searched = url + '#/?q=food&page_number=1&sort=relevance',
driver,
resultsA, resultsB, resultsC,
page,
site;
this.Given(/^I visit blog$/, function(callback) {
browser.get(url);
driver = browser.driver;
browser.getTitle()
.then(function ( title ) {
expect(browser.getTitle()).to.eventually.equal(arg1).and.notify(callback);
});
});
this.Then(/^I should see a disclaimer$/, function(callback) {
element( by.css ( '.disclaimer' ) )
.isDisplayed()
.then(function (el) {
expect(el).to.have.length(1);
callback();
});
});
};
Cheers
You never mentioned setting up a local selenium server. Did you forget it?
./node_modules/protractor/bin/webdriver-manager update
./node_modules/protractor/bin/webdriver-manager start
Just let that run in its own terminal window, and try running your tests again.
Any chance you already have another instance of webdriver running? Or a firewall that is blocking the connection?
This is a working example that I found. However it is in .coffee
https://github.com/whyvez/angular-cucumber-example

Resources