The Story:
We have a rather huge end-to-end protractor test codebase. We have two configs - one is "local" - to run the tests in Chrome and Firefox using directConnect, and the other one is "remote" - to run tests on a remote selenium server - BrowserStack in our case.
Our "local" config is configured to run some tests in Chrome and some in Firefox - because we really cannot run some tests in Chrome - for instance, keyboard shortcuts don't work in Chrome+Mac. Running the tests that require using keyboard shortcuts in Firefox is a workaround until the linked chromedriver issue is resolved.
Here is the relevant part of the configuration:
var firefox_only_specs = [
"../specs/some_spec1.js",
"../specs/some_spec2.js",
"../specs/some_spec3.js"
];
exports.config = {
directConnect: true,
multiCapabilities: [
{
browserName: "chrome",
chromeOptions: {
args: ["incognito", "disable-extensions", "start-maximized"]
},
specs: [
"../specs/**/*.spec.js",
"../specs/**/**/*.spec.js",
"../specs/**/**/**/*.spec.js"
],
exclude: firefox_only_specs
},
{
browserName: "firefox",
specs: firefox_only_specs
}
],
// ...
};
The problem:
Now, the problem is that, if I'm debugging a single test, or want to run a single test - I'm marking it is as focused (via fdescribe/fit) - but protractor starts two driver sessions - one for Chrome and the other one for Firefox, using both configured capabilities:
Running "protractor:local" (protractor) task
[launcher] Running 2 instances of WebDriver
...
------------------------------------
[chrome #1] PID: 2329
[chrome #1] Using ChromeDriver directly...
[chrome #1] Spec started
...
------------------------------------
[firefox #2] PID: 2330
[firefox #2] Using FirefoxDriver directly...
[firefox #2] Spec started
...
The question:
Is there a way to tell protractor to use the only one capability that has a focused spec configured?
Using currently latest protractor 3.0.0.
Hope the question is clear. Let me know if you need any additional information.
I wonder if you can do something to wrap the it statements like:
onPrepare: function() {
browser.getCapabilities().then(function(caps) {
global.browserName = caps.caps_.browserName;
});
global.firefoxOnly = function(name, testFunction) {
if (browserName === 'firefox') {
return it(name, testFunction);
} else {
return xit(name, testFunction).pend('firefox only');
}
};
}
Then when you write a test, instead of it use something like:
describe('when I do something', function() {
firefoxOnly('it should do the right thing', function() {
doSomething();
expect(thing).toBe(right);
)};
});
I have no idea if this actually works, just throwing it out there. In fact, when I get back to my testing computer and try it out, I would be interested in adding a function like wip to use instead of xit to automatically pend my ATDD tests!
Is there a way to tell protractor to use the only one capability that has a focused spec configured?
According to the relevant github issue, it is not possible.
Related
Hi all so I am trying to run headless chromium with protractor and jasmine. I have everything setup and working for both firefox and chrome with a head. When I run firefox headless it works... when I try running chromium headless it ends up timing out. Looking for some help to solve this problem.
The error I get is :
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Now I've read a million article online and have tried increasing the timeout time and adding done into the function as well...
Here is my current code:
Conf.js - this has a bunch of added args and settings that I've found online. I've tried pretty much every variation and had no success..
exports.config = {
framework: 'jasmine2',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec.js'],
allScriptsTimeout: 5000000,
capabilities: {
'directConnect': true,
'browserName': 'chrome',
"goog:chromeOptions": {
args: ["--headless", "--remote-debugging-port=9222", "--verbose", "--disable-gpu", "--disable-web-security", "--window-size=800x600"],
'binary': "/usr/bin/chromium-browser"
}
}
};
Spec.js - straight off of their website with console.logs. All of the console.logs print out in the following order 3,1,2. This is something I'm unsure is correct? Should the describe be waiting for the it to finish? It almost feels like my it is never returning...
describe('angularjs homepage todo list', function() {
it('should add a todo', function(done) {
console.log("WOOO1");
browser.get('https://angularjs.org');
element(by.model('todoList.todoText')).sendKeys('write first protractor test');
element(by.css('[value="add"]')).click();
var todoList = element.all(by.repeater('todo in todoList.todos'));
expect(todoList.count()).toEqual(3);
expect(todoList.get(2).getText()).toEqual('write first protractor test');
// You wrote your first test, cross it off the list
todoList.get(2).element(by.css('input')).click();
var completedAmount = element.all(by.css('.done-true'));
expect(completedAmount.count()).toEqual(2);
console.log("WOO2");
}, 15000);
console.log("WOO3");
});
Following this some other discoveries I have found... when I go to the localhost:9222 I see
Inspectable WebContents
data:text/html,<html></html>
The data:text/html,<html></html> is a link and if clicked on takes me to the remote chrome debugger that is loading ... data:text/html,. This is where I think the problem is. Why is this never actually loading the angular site?
Maybe I'm off base but does anyone know how to make sense of this?
EDIT:
Additional useful information.
I am using
chromium 79.0.3945.130
chromedriver 79.0.3945.36
jasmine v3.5.0
jasmine-core v3.5.0
Protractor 5.4.3
Thanks
Config that ended up working for me
exports.config = {
framework: 'jasmine',
allScriptsTimeout: 9000,
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec.js'],
capabilities: {
'directConnect': true,
'browserName': 'chrome',
"goog:chromeOptions": {
args: ["--headless", "--remote-debugging-port=9222", "--verbose", "--disable-gpu", "--disable-web-security", "--window-size=800x600"],
'binary': "path to chrome"
}
}
};
add allScriptTimeOut in your configuration like this:
exports.config = {
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
specs: ['example_spec.js'],
allScriptsTimeout: 9000
};
hope this link will help you
https://www.protractortest.org/#/timeouts.
I have multiple tests in my tests folder where the naming conventions for all the tests ends with spec.js. I am running all the tests from the Config file with */spec.js option.
I want to skip running one test in FF as it is not supported in that browser. This is what I am attempting to do but it is not skipping that tests. Please advise.
multiCapabilities: [{
'browserName': 'chrome',
'chromeOptions' : {
args: ['--window-size=900,900']
// }
},
},
{
'browserName': 'firefox',
'chromeOptions' : {
args: ['--window-size=900,900']
// }
},
}],
specs: [
'../tests/*.spec.js'
],
I have the following in my onPrepare function:
browser.getCapabilities().then(function (cap) {
browser.browserName = cap.caps_.browserName;
});
In one of the test file where I am looking to skip running this test in FF, I am doing this
if(browser.browserName=='firefox') {
console.log("firefox cannot run *** tests")
} else {
blah... rest of the tests which I want to execute for Chrome and IE I have put it in this block}
But still the test which I wanted to skip running in FF still runs.
Please advise.
An easy way to do this is to update your firefox multicapabilities to exclude particular test spec using exclude tag. This prevents use of an if condition and additional lines of code. More details are here. Here's how -
multiCapabilities: [{
browserName: 'chrome',
chromeOptions : {
args: ['--window-size=900,900']
},
},
{
browserName: 'firefox',
// Spec files to be excluded on this capability only.
exclude: ['spec/doNotRunInChromeSpec.js'], //YOUR SPEC NAME THAT YOU WANT TO EXCLUDE/SKIP
}],
Hope it helps.
As soon as browser.getCapabilities() is asynchronous and is based on Promises, your code inside .then() may be executed later than the rest of the code. I guess your if condition is placed inside describe block, which actually runs before the value for browser.browserName is set, as a result you get a value of undefined for it and condition fails. To make sure that your tests run after all the preparations are done, you should return a promise from onPrepare:
onPrepare: function() {
return browser.getCapabilities().then(function (cap) {
browser.browserName = cap.caps_.browserName;
});
}
Protractor will explicilty wait until it resolves and then start executing the tests.
describe('Suite', function () {
console.log(browser.browserName); // 'firefox'
it('spec', function () {
expect(true).toBe(true);
});
});
I want to run protractor test using Firefox and phantomJS instead of chrome. However it will only run when I specify the 'chromeOnly: true' option and specify Chrome as the browser.
Otherwise it will crash and throw the error 'unable to start Webdriver Session'.
My protractor config:
'use strict';
var paths = require('./.yo-rc.json')['generator-gulp-angular'].props.paths;
// An example configuration file.
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
//seleniumServerJar: deprecated, this should be set on node_modules/protractor/config.json
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'firefox'
},
//chromeOnly: true,
baseUrl: 'http://localhost:8000/',
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: [paths.e2e + '/**/*.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
The "chromeOnly" option means "connect directly to chrome" (vs. using a selenium server). When you remove that option, Protractor is expecting to talk to a selenium server to control a browser. See https://github.com/angular/protractor/blob/master/docs/server-setup.md.
Since Firefox now also supports a "direct connect" mode, the "chromeOnly" configuration option has been renamed to "directConnect". See https://github.com/angular/protractor/commit/3c048585ac811726d6c6d493ed6d43f6a3570bee
To use Firefox directly you can either leave the mis-named "chromeOnly" option set, or switch to "directConnect". Or, you can use Firefox via a selenium server (which just means you need to start the selenium server up, see the server-setup.md doc listed above).
Notice using phantomjs with protractor is disregarded.
Taken from http://angular.github.io/protractor/#/browser-setup
Add phantomjs to the driver capabilities, and include a path to the binary if using local installation:
capabilities: {
'browserName': 'phantomjs',
/*
* Can be used to specify the phantomjs binary path.
* This can generally be ommitted if you installed phantomjs globally.
*/
'phantomjs.binary.path': require('phantomjs').path,
/*
* Command line args to pass to ghostdriver, phantomjs's browser driver.
* See https://github.com/detro/ghostdriver#faq
*/
'phantomjs.ghostdriver.cli.args': ['--loglevel=DEBUG']
}
use
multiCapabilities : [
{
'browserName' : 'chrome',
'chromeOptions' : {
'binary' : 'chrome.exe',
'args' : [],
'extensions' : []
},
{
'browserName' : 'firefox',
'chromeOptions' : {
'binary' : 'path to firefox.exe',
'args' : [],
'extensions' : []
}...
}
Dojo 1.9 and Intern 1.7
I am having a problem with Intern in that it's reporting that require.on is not defined and my test suite is falling over.
This is only happening when trying to define a test that includes a widget. it looks like when the widget package is requried then it hits a line require.on("idle", onload) but fails because require.on is undefined.
As a test, I defined require.on and the test does not fall over.
All I can think of is that the version of dojo that intern ships with is interfering with the normal dojo module when requiring widgets using intern?
Here is a cut down version of my test:
define([
"intern!object",
"intern/chai!expect",
"dijit/form/Button"
],
function (
registerSuite,
expect,
Button) {
registerSuite({
name: "Simple test",
"failing test for demo" : function (){
expect(true).to.be.false;
}
});
});
Here is my configuration:
define({
// The port on which the instrumenting proxy will listen
proxyPort: 9000,
// A fully qualified URL to the Intern proxy
proxyUrl: 'http://localhost:9000/',
// Default desired capabilities for all environments. Individual capabilities can be overridden by any of the
// specified browser environments in the `environments` array below as well. See
// https://code.google.com/p/selenium/wiki/DesiredCapabilities for standard Selenium capabilities and
// https://saucelabs.com/docs/additional-config#desired-capabilities for Sauce Labs capabilities.
// Note that the `build` capability will be filled in with the current commit ID from the Travis CI environment
// automatically
capabilities: {
'selenium-version': '2.40.0'
},
// Browsers to run integration testing against. Note that version numbers must be strings if used with Sauce
// OnDemand. Options that will be permutated are browserName, version, platform, and platformVersion; any other
// capabilities options specified for an environment will be copied as-is
environments: [
{ browserName: 'chrome' }
],
// Maximum number of simultaneous integration tests that should be executed on the remote WebDriver service
maxConcurrency: 3,
// Whether or not to start Sauce Connect before running tests
useSauceConnect: false,
// Connection information for the remote WebDriver service. If using Sauce Labs, keep your username and password
// in the SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables unless you are sure you will NEVER be
// publishing this configuration file somewhere
webdriver: {
host: 'localhost',
port: 4444
},
// Configuration options for the module loader; any AMD configuration options supported by the specified AMD loader
// can be used here
loader: {
// Packages that should be registered with the loader in each testing environment
packages: [
{
name: "dojo",
location: "libs/dojo"
}{
name: "dijit",
location: "libs/dijit"
},{
name: "unitTests",
location: "test/unit"
}
]
},
// Non-functional test suite(s) to run in each browser
suites: [ /* 'myPackage/tests/foo', 'myPackage/tests/bar' */
"unitTests/exampleTest"
],
// Functional test suite(s) to run in each browser once non-functional tests are completed
functionalSuites: [ /* 'myPackage/tests/foo', 'myPackage/tests/bar' */
],
// A regular expression matching URLs to files that should not be included in code coverage analysis
excludeInstrumentation: /^tests\//
});
Folder structure is:
app/
libs/
dojo
dijit
intern
test/
unit/
exampleTest.js
intern.js
I am running the test straight from the google chrome browser:
http://{webroot}/app/libs/intern/client.html?config=../test/intern
I do have some tests that run successfully but do not include any widgets.
Thanks for any help.
You are running an outdated version of Dojo 1.9 that expects that the AMD loader being used is the one that comes with Dojo 1.9, which is not the case in a default installation of Intern. You have two options:
Upgrade to Dojo 1.9.3 or later. (Recommended.)
Use the useLoader configuration option to point to dojo.js from your copy of Dojo 1.9:
define({
// ...
useLoader: {
'host-browser': 'path/to/dojo1.9/dojo.js'
}
})
I have the following setup:
buster.js:
var config = module.exports;
config["web-module"] = {
autoRun: true,
environment: "browser",
rootPath: ".",
libs: [
//"app/webroot/src/lib/underscore.js"
],
sources: [
],
tests: [
"buster_simpletest.js"
]
};
buster_simpletest.js:
buster.testCase("My thing", {
"states the obvious": function () {
console.log("TEST");
assert(true);
}
});
This setup runs fine and I get the expected console output:
Chrome 24.0.1312.57, Windows Server 2008 R2 / 7:
Passed: Chrome 24.0.1312.57, Windows Server 2008 R2 / 7 My thing states the obvious
[LOG] TEST
1 test case, 1 test, 1 assertion, 0 failures, 0 errors, 0 timeouts.
Finished in 0.004s
However, it doesn't as soon as I include any of the libs (I tried underscore.js, jQuery and several others.)
I don't get a single line of console output. No error, no nothing. It simply freezes there.
I also tried to disable autoRun and include a run.js which calls buster.run();, but the result was the same.
Does anyone know what's wrong here?
Thanks in advance for your help.
Edit:
Ok I tested some more and it seems to have problems with the folder depth. Here is my folder structure:
root
- buster.js
- buster_simpletest.js
- underscore.js
- a
- underscore.js
- b
- underscore.js
And here's my testing result:
libs: [
//"underscore.js" // works
//"a/underscore.js" // works
//"a/b/underscore.js" // freezes
//"a/b/xunderscore.js" // Error: "Failed loading configuration: "a/b/xunderscore.js" matched no files or resources"
]
As you can see it freezes as soon as I have depth of 2 folders. Although it is able to find the file, as I get an error if I try to include an invalid file.
Edit 2:
Seems to be a bug with windows only. The same setup works fine on our linux machine.
I guess we have to wait for proper windows support.