When running a test in mocha using the selenium webdriver for JavaScript the call-stack it not really helpful.
As a simple example I've used the following simple test script test.js:
var webdriver = require('selenium-webdriver'),
test = require('selenium-webdriver/testing');
const TIMEOUT = 30000;
test.describe('selenium webdriverjs', function () {
var driver;
this.timeout(TIMEOUT);
test.before(function () {
driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.firefox()).build();
driver.manage().timeouts().pageLoadTimeout(TIMEOUT);
});
test.after(function () {
driver.quit();
});
test.it('error stack', function () {
driver.get('http://www.google.com');
driver.findElement(webdriver.By.id('doesnotexit'));
});
});
that generates the following error stack when (for example) run from Gulp:
selenium webdriverjs
1) error stack
0 passing (4s)
1 failing
1) selenium webdriverjs error stack:
NoSuchElementError: Unable to locate element: {"method":"id","selector":"doesnotexit"}
at new bot.Error (...\node_modules\selenium-webdriver\lib\atoms\error.js:108:18)
at Object.bot.response.checkResponse (...\node_modules\selenium-webdriver\lib\atoms\response.js:109:9)
at ...\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:379:20
at promise.Promise.goog.defineClass.invokeCallback_ (.../node_modules/selenium-webdriver/lib/goog/../webdriver/promise.
js:1337:14)
at promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_.execute_ (.../node_modules/selenium-
webdriver/lib/goog/../webdriver/promise.js:2776:14)
at promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_ (.../node_modules/selenium-webdriver
/lib/goog/../webdriver/promise.js:2758:21)
at goog.async.run.processWorkQueue (...\node_modules\selenium-webdriver\lib\goog\async\run.js:124:15)
From: Task: selenium webdriverjs error stack
at Context.ret (...\node_modules\selenium-webdriver\testing\index.js:128:10)
at callFnAsync (...\node_modules\mocha\lib\runnable.js:306:8)
at Test.Runnable.run (...\node_modules\mocha\lib\runnable.js:261:7)
at Runner.runTest (...\node_modules\mocha\lib\runner.js:421:10)
at ...\node_modules\mocha\lib\runner.js:528:12
at next (...\node_modules\mocha\lib\runner.js:341:14)
at ...\node_modules\mocha\lib\runner.js:351:7
at next (...\node_modules\mocha\lib\runner.js:283:14)
at Immediate._onImmediate (...\node_modules\mocha\lib\runner.js:319:5)
The stack consists of a series of deeply nested function in the mocha and selenium libraries of the local node_modules directory and actual test script test.js is not even part of the stack.
I'm wondering, if this is really the best information I can get from this setup if I just did something wrong?
Yes, this is really too much unnecessary and not really helpful information with all of the meaningless async traceback cruft, but the most important part of it, the webdriver error itself, is on top and is pretty self-descriptive:
NoSuchElementError: Unable to locate element:
{"method":"id","selector":"doesnotexit"}
You may try to clean up the output with the help of mocha-clean package. When applied, it should really leave the error message itself and only relevant parts of the stack trace eliminating everything mocha- and selenium-webdriver-specific:
Mocha stack traces are riddled with frames that you don't want to see,
like code from modules and Mocha internals. It strips away mocha
internals, node_modules, absolute paths (based on cwd), and other
unneccessary cruft.
Related
I want to toggle only running one test, so I don't have to wait for my other tests to see the result of one test.
Currently, I comment out my other tests, but this is really annoying.
Is there a way to toggle only running one test in Cypress?
to run only one file
cypress run --spec path/to/file.spec.js
or using glob patterns:
cypress run --spec 'path/to/files/*.spec.js'
Note: you need to wrap your glob patterns in single quotes to avoid shell expansion!
to run only one test in a file
You can use a .only as described in the Cypress docs
it.only('only run this one', () => {
// similarly use it.skip(...) to skip a test
})
it('not this one', () => {
})
Also, you can do the same with describe and context blocks
edit:
there's also a nice VSCode extension to make adding/removing .only's easier with keyboard shortcuts. It's called Test Utils (install with ext install chrisbreiding.test-utils). It works with js, coffee, and typescript:
There are multiple ways of achieving this.
You can add .onlyto it or describe see #bkucera answer
You can do it from the terminal as explained in the doc here
npx cypress run --record --spec "cypress/integration/my-spec.js"
npm run cypress -- --record --spec "cypress/integration/my-spec.js"
You can mute not needed test suites and particular cases by prepending x to testrunner methods call (describe, it, etc.)
So it would look like:
// this whole testsuite will be muted
xdescribe('Visit google', () => {
it('should visit google', () => { cy.visit('https://google.com/'); });
});
// this testsuite will run
describe('Visit youtube', () => {
it('should visit youtube', () => { cy.visit('https://youtube.com/'); });
// this testcase will be muted
xit('is not necessary', () => { ... });
});
You can run the test like this.
cypress run --spec **/file.js
The best way to do such kind runs are by using the .only keyword that cypress provide.
To run all the test cases in one describe function from many describe functions add the .only in the required describe.
describe("1st describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
describe.only("2nd describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
describe("3rd describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
So here only the 2nd describe will run.
Similarly if you want to run some test cases in 1 describe add the .only in front of all the test cases that you want to run.
describe("describe statement", () => {
it("Should check xx", async function(){
});
it.only("Should check yy", async function(){
});
it.only("Should check zz", async function(){
});
});
So here the it for yy and zz will run
This is similar to the fit and fdescribe in karma and jasmine that you might be familiar with.
You can skip the test in cypress with it.skip or xit
There is one way I have found to skip tests which I don't need to run (in the current test), and that is to use: this.skip();
it('test page', function () {
// skip this test for now
this.skip();
cy.visit('http://example.com/')
cy.contains('test page').click()
cy.url()
.should('include', '/test-page/')
})
1. it is important to use regular function as second argument of it, this will not be available in arrow function
2. Whole of the test will be skipped no matter where we write this.skip()
My test files have a structure like this path/something.test.jsx and commands npx cypress run --spec path/something.test.jsx gives the following exception in the terminal:
Can't run because no spec files were found.
We searched for any files matching this glob pattern:
...
Surprisingly enough the following works and run the test exactly for one file (providing you have jest installed):
jest path/something.test.jsx
A very easy solution is to prefix your tests in with numbers, as testing frameworks will typically will run tests in alpha/numeric order by default - so if I have to check one spec file - I will copy the contents into a file 0-[file-name].spec and re-run the test command. Once the test completes - you terminate the test run - as you will have the results you were looking for. This answer is targeted at projects where your testing framework is abstracted and as a developer, you do not have all available options for your testing framework. Not the best answer, but it works and is intuitive and super easy to do. I have found this to be a way to avoid adding a bunch of conditional skips() or only() calls that will not make it to production, will have to be removed and you can easily add the file pattern to .gitignore file so these local files do not get checked in.
The best-known solution for that already exists and requires adding just one simple argument in the console.
https://github.com/cypress-io/cypress/tree/develop/npm/grep
Simply run:
npx cypress run --env grep="TestName" --spec "filename"
Cypress .only() function is used only for development.
put .only for the test you want to execute and then run the spec as npx cypress run --spec path/to/your-file.spec.js
To run a specific file through Terminal:
npx cypress run --record --spec "cypress/integration/my-spec.js"
npm run cypress -- --record --spec "cypress/integration/my-spec.js"
You can use this
cypress run -- --spec 'path/to/files/*.spec.js'
or
npm run --spec 'path/to/files/*.spec.js'
It worked for me.
Many thanks
use the #focus keyword in the test scripts when execute using cypress open
Working on getting a project transitioned over from Mocha to Jest to take advantage of the speed in running tests as well as the Jest framework itself and running into an issue. Rewire is used pretty extensively in the codebase and I'm having an issue when running the gulp-jest task and only for those files that use rewire. I assume it has something to do with modules loading or not loading, but I'm stumped. Here's the really bare-bones gulp task, doesn't have much to it. I've already run through an extensive codemod on the codebase and many tests pass, just not those that use rewire.
gulp.task('jest', function() {
process.env.NODE_ENV = 'test';
return gulp.src('name/path').pipe(
jest({
preprocessorIgnorePatterns: ['<rootDir>/node_modules/'],
automock: false,
resetModules: true,
setupFiles: ['./jestsetup.js']
})
);
});
gulp.task('newtest', function(callback) {
runSequence('env', 'jest', callback);
});
Any time the rewire-related files are run, they complain about the file not being found. Am I missing anything here? I'm certain the modules themselves have the correct path set for the require.
Here's the actual error from jest/rewire:
FAIL path/to/folder/file/app.test.js
● Test suite failed to run
Cannot find module '../../../../path/to/folder/file/app'
at Function.Module._resolveFilename (module.js:469:15)
at internalRewire (node_modules/rewire/lib/rewire.js:23:25)
at rewire (node_modules/rewire/lib/index.js:11:12)
at Object.<anonymous (path/to/folder/file/app.test.js:10:14)
at process._tickCallback (internal/process/next_tick.js:109:7)
Using node 6.X, jest 20.x
Thanks in advance!
Jest has its own mechanism of mocking import, it's called jest.mock.
You will need to switch to using that instead of rewire.
Example
// banana.js
module.exports = () => 'banana';
// __tests__/test.js
jest.mock('../banana');
const banana = require('../banana'); // banana will be explicitly mocked.
banana(); // will return 'undefined' because the function is auto-mocked.
example was taken from here
To my surpise, Proxyquire was not compatible with jest. To mock a dependency you would need to utilize a mocking library, like rewiremock.
Please have a look at this answer and this REPL example on how to successfully mock dependent packages.
I am currently using protractor, cucumber and chai/chai-as-promised for my automated tests. My current code is using protractor 1.8.0 and I would like to update it to the most recent version. The problem is that the most recent version of protractor doesn't support cucumber.
To use cucumber as your framework, protractor (http://angular.github.io/protractor/#/frameworks) points you to using protractor-cucumber-framework (https://github.com/mattfritz/protractor-cucumber-framework). I have tried integrating this with my current code and some smaller example projects with no luck at getting them working. The main error I get is:
Error: Step timed out after 5000 milliseconds at Timer.listOnTimeout
(timers.js:92:15)
I have tried changing the default timeout globally as cucumber suggests by:// features/support/env.js
var configure = function () {
this.setDefaultTimeout(60 * 1000);
};
module.exports = configure;
But I seem to be missing something with my setup.
So, does anyone know of a good example that can show me the proper setup for the new protractor/cucumber framework? If not, does anyone know of an example that shows how to change the default timeout globally?
You should add
this.setDefaultTimeout(60000);
to one of your step_def files. For example:
module.exports = function () {
this.setDefaultTimeout(60000);
this.After(function (callback) { ... }
}
Or you should add //features/support/env.js to
cucumberOpts:{require: ['//features/support/env.js']}
to array with your stepDefinition files
thx to #Ivan,
with cucumber-protractor-framework and typescript:
in protractor.conf.js
cucumberOpts: {
compiler: "ts:ts-node/register",
require: [
'./src/env.ts', //<- added
'./src/**/*.steps.ts'
]
},
in src/env.ts:
import {setDefaultTimeout} from 'cucumber';
setDefaultTimeout(9001);
I am having a hard time trying to run tests with Mocha and RequireJS in the browser.
My attempt is based on https://gist.github.com/michaelcox/3800736
I had to diverge from that example, because my main issue is that require('mocha') always errors with "Module name "lib/mocha" has not been loaded yet for context".
But somehow magically I see that global Mocha is instantiated. I invoke it as a constructor, but the run of new Mocha() does not prepare the interface (describe, etc.)
I see that the problem is that an inner call to
this._ui = this._ui(this.suite);
leaves this._ui undefined, apparently because array this.suite.tests is empty, which is explainable as I still have to read the test suite file.
Here are the details. If anyone can shed some light, I'll be very grateful.
I start from a single HTML tag loading require.js with a data-main.
<script data-main="./js_modular/spec-runner" src="./js_modular/lib/require.js"></script>
My data-main file (not working!) is the following:
require.config({
'paths': {
'mocha': './lib/mocha',
'chai': './lib/chai',
'sinon': './lib/sinon-1.11.1'
}
});
define(['require', 'exports', 'mocha'], (function(require, exports, mocha) {
// mocha is undefined, but Mocha is not
var mocha = new Mocha({ ui: 'bdd' }); // mocha misses the characteristic methods of the bdd interface, though...
require([
'./geiesadts_test', // load of test file fails because describe is undefined
], function(require) {
mocha.run(); // never got till here :-(
});
}));
Thank you for your attention.
My JS code is usually full of console.log() debug messages. Sometimes it is better to turn them off, or to turn off some part of them.
I can, for example, wrap console.log() statement in some function with conditions which are defined by some constants. Is it the best way to manage debug output or are more elegant alternatives?
Bunyan logging module is popular for node.js
Example code hi.js:
var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'myapp'});
log.info('hi');
log.warn({lang: 'fr'}, 'au revoir');
Output:
{"name":"myapp","hostname":"localhost","pid":40161,"level":30,"msg":"hi","time":"2013-01- 04T18:46:23.851Z","v":0}
{"name":"myapp","hostname":"localhost","pid":40161,"level":40,"lang":"fr","msg":"au revoir","time":"2013-01-04T18:46:23.853Z","v":0}
You can then filtering from command lines:
$ node hi.js | bunyan -l warn
[2013-01-04T19:08:37.182Z] WARN: myapp/40353 on localhost: au revoir (lang=fr)
Wrapping console.log into a function works well. But notice that there are also a lot of logging utilities out there for javascript. A little google on "js logger" may yield suitable results.
If you're using Node.js then debug is extremely effective as an alternative to console.log()
It's basically a substitute for console.log() except you can enable it at the command line with the DEBUG environment variable based on how you've initialized it in each file.
Let's say I have a project with a couple of files referenced from my index.js file:
one.js
var debug = require('debug')('one-one');
var func = function() {
debug('func');
}
two.js
var debug = require('debug')('one-two');
var func = function() {
debug('func');
}
You've initialized debug with the name "one-one" in the first file and "one-two" in the second file.
On the command line I can run them like this:
node index.js
Result: no debug output. However, if I run it like this:
DEBUG=* node index.js
The both the debug statements will get written out, however, in different colors and with the debug name (one-one or one-two) so I can tell which file they came from.
Now let's say you want to narrow it down a bit more. You could run:
DEBUG=*-two node index.js
To only get output from debug that's been set with "-two" at the end of the name or
DEBUG=one-* node index.js
to get everything starting with "one-"
You can also say that you want everything, or a set of things, or exclude patterns or sets. To exclude something you precede it with a dash, an example:
DEBUG=one*,monkey*,-monkey:banana,-elephant,-chimp:* node index.js
This will include everything starting with "one" or "monkey" and exclude anything called "monkey:banana", or "elephant" or starting with "chimp:"
If you wanted to exclude everything except then:
DEBUG=*,-pattern1,-pattern2 node index.js
JS logger is quite good and lightweight tool with flixible settings for log messages levels and several predefined logging levels (DEBUG, INFO, WARN, ERROR).