getByRole in Nightwatch Testing Library throws error in basic example - nightwatch.js

I keep getting an error when running a basic sample with Nightwatch.js + Testing Library:
[Ecosia Search With TL] Test Suite
==================================
ℹ Connected to localhost on port 9515 (1077ms).
Using: chrome (87.0.4280.66) on Mac OS X platform.
Running: Demo test ecosia.org
matcher.test is not a function
FAILED: 1 errors (935ms)
_________________________________________________
TEST FAILURE: 1 error during execution; 0 tests failed, 0 passed (2.779s)
✖ ecosiaSearchWithTL
– Demo test ecosia.org (935ms)
Error: [object Object]
at processTicksAndRejections (internal/process/task_queues.js:97:5)
npm ERR! Test failed. See above for more details.
This is my only test:
const { getQueriesFrom } = require('#testing-library/nightwatch')
module.exports = {
async beforeEach(browser) {
await browser.url('https://www.ecosia.org/')
},
async 'Demo test ecosia.org'(browser) {
const { getByRole } = getQueriesFrom(browser)
const searchBox = await getByRole('searchbox', { name: /search form/i })
browser.setValue(searchBox, 'nightwatch')
const submit = await getByRole('button', { name: /submit/i })
browser.click(submit)
browser.end()
}
}
My nightwatch.conf.js:
module.exports = {
src_folders: ['tests'],
webdriver: {
start_process: true,
port: 9515,
server_path: "node_modules/.bin/chromedriver",
},
test_settings: {
default: {
desiredCapabilities : {
browserName: "chrome"
}
}
}
};
Any idea why I keep getting that error?
It works flawlessly without Testing Library.

Related

Is it possible to run Angular Cypress Test with K6?

We have a lot of cypress tests in our Angular Project. But we want to use k6 as our new main load testing tool. But also we want to keep our already written cypress tests.
Is it possible to execute cypress tests within k6? e.g run k6 with 1000 VUs but instead of k6 test script, use cypress test scrpts.
There's an article here: Using Cypress to automate k6 scripts recording
Lots of steps, but to update for Cypress v10 the syntax for the before:browser:launch hook:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:browser:launch', (browser, launchOptions) => {
if (browser.isHeaded) {
try {
launchOptions.extensions.push(...);
} catch (error) {
console.log("extension not available"); //when in headless mode
}
return launchOptions;
}
})
},
// other config
}
Answer above was a solid suggestion. I used that article indicated there, only slight modifications (i mentioned it on the medium post).
for cypress 10+, under cypress.config.js
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:browser:launch', (browser = {}, launchOptions) => {
console.log(launchOptions.args) // print all current args
//Mac and Linux path
//const k6path = "k6Files/k6-Browser-Recorder"
//Windows path
const k6path = "C:\\Users\\..."
if (browser.isHeaded) {
try {
launchOptions.extensions.push(k6path);
} catch (error) {
console.log("extension not available"); //when in headless mode
}
return launchOptions
}
})
},
},
});
if your using env config files like cypress.dev-config.js then above goes in that e2e section
Rest of instruction on the post should work just fine.

Can passed nightwatch.js tests be hidden in output?

The default Nightwatch.js output consumes one line per passed test. For example,
✔ Testing if element <body> contains text 'lecture is so boring' (12ms)
✔ Testing if element <button[id=btn1]> is visible (6ms)
✔ Testing if element <button[id=btn]> is visible (10ms)
✔ Testing if element <#fill1> is visible (19ms)
✔ Testing if element <#fill2> is visible (18ms)
✔ Testing if element <#fill3> is visible (20ms)
Currently Nightwatch consumes far more of my screen than the rest of my build output combined. On the CLI on Linux, appending
|grep -v "✔"
to the command mostly alleviates that but has the disadvantage of stripping colored text (even with --color=always) when calling nightwatch from gulp. Is there a configuration option or command line parameter to minimize output and only show failed tests?
Ideally, if all tests pass, I would prefer just one line of output, but that may be asking too much. Using the grep above, this still results, which remains too much for my taste.
[Nightwatch] Test Suite
=======================
ℹ Connected to localhost on port 4444 (1133ms).
Using: firefox (91.0.1) on linux 4.19.0-18-amd64 platform.
Running: Demo of Quiz
OK. 51 assertions passed. (3.498s)
I'd really just like it to say
Nightwatch: 51 assertions passed. (3.498s)
or similar.
My config file:
// Autogenerated by Nightwatch
// Refer to the online docs for more details: https://nightwatchjs.org/gettingstarted/configuration/
const Services = {}; loadServices();
module.exports = {
// An array of folders (excluding subfolders) where your tests are located;
// if this is not specified, the test source must be passed as the second argument to the test runner.
src_folders: ['src/ts/test/functional'],
// See https://nightwatchjs.org/guide/working-with-page-objects/
page_objects_path: '',
// See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
custom_commands_path: '',
// See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions
custom_assertions_path: '',
// See https://nightwatchjs.org/guide/#external-globals
globals_path : '',
webdriver: {},
test_settings: {
default: {
disable_error_log: false,
launch_url: 'https://nightwatchjs.org',
screenshots: {
enabled: false,
path: 'screens',
on_failure: true
},
desiredCapabilities: {
browserName : 'firefox'
},
webdriver: {
start_process: true,
server_path: (Services.geckodriver ? Services.geckodriver.path : '')
}
},
firefox: {
desiredCapabilities : {
browserName : 'firefox',
alwaysMatch: {
// Enable this if you encounter unexpected SSL certificate errors in Firefox
// acceptInsecureCerts: true,
'moz:firefoxOptions': {
args: [
// '-headless',
// '-verbose'
],
}
}
},
webdriver: {
start_process: true,
port: 4444,
server_path: (Services.geckodriver ? Services.geckodriver.path : ''),
cli_args: [
// very verbose geckodriver logs
// '-vv'
]
}
},
chrome: {
desiredCapabilities : {
browserName : 'chrome',
chromeOptions : {
// This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
// w3c: false,
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
args: [
//'--no-sandbox',
//'--ignore-certificate-errors',
//'--allow-insecure-localhost',
//'--headless'
]
}
},
webdriver: {
start_process: true,
port: 9515,
server_path: (Services.chromedriver ? Services.chromedriver.path : ''),
cli_args: [
// --verbose
]
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using the browserstack.com cloud service |
// |
// Please set the username and access key by setting the environment variables: |
// - BROWSERSTACK_USER |
// - BROWSERSTACK_KEY |
// .env files are supported |
//////////////////////////////////////////////////////////////////////////////////
browserstack: {
selenium: {
host: 'hub-cloud.browserstack.com',
port: 443
},
// More info on configuring capabilities can be found on:
// https://www.browserstack.com/automate/capabilities?tag=selenium-4
desiredCapabilities: {
'bstack:options' : {
local: 'false',
userName: '${BROWSERSTACK_USER}',
accessKey: '${BROWSERSTACK_KEY}',
}
},
disable_error_log: true,
webdriver: {
keep_alive: true,
start_process: false
}
},
'browserstack.chrome': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'chrome',
chromeOptions : {
// This tells Chromedriver to run using the legacy JSONWire protocol
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
w3c: false
}
}
},
'browserstack.firefox': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'firefox'
}
},
'browserstack.ie': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'IE',
browserVersion: '11.0',
'bstack:options' : {
os: 'Windows',
osVersion: '10',
local: 'false',
seleniumVersion: '3.5.2',
resolution: '1366x768'
}
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using the Selenium service, either locally or remote, |
// like Selenium Grid |
//////////////////////////////////////////////////////////////////////////////////
selenium: {
// Selenium Server is running locally and is managed by Nightwatch
selenium: {
start_process: true,
port: 4444,
server_path: (Services.seleniumServer ? Services.seleniumServer.path : ''),
cli_args: {
'webdriver.gecko.driver': (Services.geckodriver ? Services.geckodriver.path : ''),
'webdriver.chrome.driver': (Services.chromedriver ? Services.chromedriver.path : '')
}
}
},
'selenium.chrome': {
extends: 'selenium',
desiredCapabilities: {
browserName: 'chrome',
chromeOptions : {
w3c: false
}
}
},
'selenium.firefox': {
extends: 'selenium',
desiredCapabilities: {
browserName: 'firefox',
'moz:firefoxOptions': {
args: [
// '-headless',
// '-verbose'
]
}
}
}
}
};
function loadServices() {
try {
Services.seleniumServer = require('selenium-server');
} catch (err) {}
try {
Services.chromedriver = require('chromedriver');
} catch (err) {}
try {
Services.geckodriver = require('geckodriver');
} catch (err) {}
}
Edit: Just to mark it as answered
You need to add detailed_output: false in your nightwatch config file.

Can't write out protractor network/performance log in a custom jasmine reporter

I'm trying to write to console the network log after a test failure as part of my protractor suite. The code works fine when in an afterEach() block but fails to execute the promise when inside of a custom jasmine reporter. As far as I can tell the promise never executes, but there are no known/shown errors.
protractor config (simplified):
exports.config = {
specs: ['./e2e/**/*.spec.ts'],
capabilities: {
browserName: 'chrome',
chromeOptions: {
perfLoggingPrefs: {
enableNetwork: true,
enablePage: false,
}
},
loggingPrefs: {
performance: 'ALL',
browser: 'ALL'
},
},
onPrepare() {
jasmine.getEnv().addReporter({
specDone: result => {
new ErrorReporter(browser).logNetworkError(result);
}
});
},
};
ErrorReporter:
class ErrorReporter {
constructor(browser) {
this.browser = browser;
}
logNetworkError(result) {
if(result.status === 'failed') {
// execution makes it in here
this.browser.manage().logs().get('performance').then(function(browserLogs) {
// execution DOES NOT make it here
browserLogs.forEach(function(log) {
const message = JSON.parse(log.message).message;
if(message.method === 'Network.responseReceived') {
const status = message.params.response.status;
const url = message.params.response.url;
if(status !== 200 && status !== 304) {
console.log(`----E2E NETWORK ERROR----`);
console.log(`STATUS: [${status}]`);
console.log(`URL: [${url}]`);
console.log(`RESPONSE: [${log.message}]`);
}
}
});
});
}
}
}
module.exports = ErrorReporter;
The code inside the logNetworkError() method works completely fine when executed in an afterEach() block but never writes out any logs when executed as a custom reporter. I would expect that this would work as a jasmine reporter as well.
If it's not possible to execute this as a jasmine reporter is there some way to access the executed test's results in the afterEach() block? I do not want to log on successful test execution.
I figured out the solution. There was 2 main problems. The first was that I needed to use async and await inside of the function that was creating the log:
async logNetworkError(result) {
if(result.status === 'failed') {
const logs = await this.browser.manage().logs().get('performance');
logs.forEach((log) => {
const message = JSON.parse(log.message).message;
if(message.method === 'Network.responseReceived') {
const status = message.params.response.status;
const url = message.params.response.url;
if(status !== 200 && status !== 304) {
console.log(`-----E2E NETWORK ERROR-----`);
console.log(`TEST NAME: ${result.fullName}`);
console.log(`STATUS: [${status}]`);
console.log(`URL: [${url}]`);
console.log(`RESPONSE: [${log.message}]`);
}
}
});
}
}
the second part of the problem was that another reporter which was saving screenshots did not have async and await which was stopping other reporters from completing. Adding async/await to both reporters solved this issue.

goolge api error { domain: 'androidpublisher', reason: 'noApks', message: 'This app has no APKs.' }

I followed the link here http://frontendcollisionblog.com/javascript/2015/12/26/using-nodejs-to-upload-app-to-google-play.html to use node to upload apk to googleapi. I always got this error
errors:
[ { domain: 'androidpublisher',
reason: 'noApks',
message: 'This app has no APKs.' } ]
This is my upload function
function upload(data) {
var edit = data.edit;
var apk = data.apk;
console.log("upload" + edit.data.id);
return new Promise(function(resolve, reject) {
play.edits.apks.upload({
editId: edit.data.id,
media: {
mimeType: 'application/vnd.android.package-archive',
body: apk
}
}, function(err, res) {
if(err || !res) {
reject(err);
}
resolve(_.omit(_.extend(data, { uploadResults: res }), 'apk'));
});
});
}
Anyone know what the error is and how to fix it?

How to get nightwatch test_workers work with browserstack-local

I am trying to get Nightwatch's inbuilt parallel test_workers working with browserstack-local for local url testing.
When running tests without browserstack local, Nightwatch test_workers seem to work just fine. The same is true for running local tests without test_workers enabled.
I have tried the examples found here https://github.com/browserstack/nightwatch-browserstack but none of these uses browserstack-local in combination with Nightwatch test_workers.
When running locally with test_workers I get the following output.
Connecting local
Connected. Now testing...
Process terminated with code 0.
Has anyone else encountered similar issues?
EDIT: I have since resolved this issue and have posted an answer below
I have dumped the relevant configuration files below.
My local.conf.js
nightwatch_config = {
globals_path: 'globals.js',
output_folder: false,
src_folders: ['tests'],
selenium: {
'start_process': false,
'host': 'hub-cloud.browserstack.com',
'port': 80
},
test_workers: {
"enabled": true,
"workers":2
},
test_settings: {
default: {
desiredCapabilities: {
'browserstack.user': process.env.BROWSERSTACK_USER,
'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
'browserstack.local': true,
'browserstack.debug': false,
}
}
}
};
// Code to copy seleniumhost/port into test settings
for (let i in nightwatch_config.test_settings) {
if (nightwatch_config.test_settings.hasOwnProperty(i)) {
let config = nightwatch_config.test_settings[i];
config['selenium_host'] = nightwatch_config.selenium.host;
config['selenium_port'] = nightwatch_config.selenium.port;
}
}
module.exports = nightwatch_config;
local.runner.js
#!/usr/bin/env node
var Nightwatch = require('nightwatch');
var browserstack = require('browserstack-local');
var bs_local;
process.env.BROWSERSTACK_ID = new Date().getTime();
try {
process.mainModule.filename = "./node_modules/.bin/nightwatch";
// Code to start browserstack local before start of test
console.log("Connecting local");
Nightwatch.bs_local = bs_local = new browserstack.Local();
bs_local.start({ 'key': process.env.BROWSERSTACK_ACCESS_KEY }, function (error) {
if (error) throw error;
console.log('Connected. Now testing...');
Nightwatch.cli(function (argv) {
Nightwatch.CliRunner(argv)
.setup(null, function () {
// Code to stop browserstack local after end of parallel test
bs_local.stop(function () { });
})
.runTests(function () {
// Code to stop browserstack local after end of single test
bs_local.stop(function () { });
});
});
});
} catch (ex) {
console.log('There was an error while starting the test runner:\n\n');
process.stderr.write(ex.stack + '\n');
process.exit(2);
}
and my package.json script
node ./local.runner.js -c ./local.conf.js
The issue here was due to the module filename being incorrectly defined in the local.runner.js
process.mainModule.filename = "./node_modules/.bin/nightwatch";
should be pointed directly at the Nightwatch file in its directory.
process.mainModule.filename = "./node_modules/nightwatch/bin/nightwatch";
The difference in these files and the exact reason for this solution working are beyond me.
The answer was derived from the "suite" runner in https://github.com/browserstack/nightwatch-browserstack
It seems you are not specifying browsers. Modify your configuration file to be inline with the following configuration file:
var browserstack = require('browserstack-local');
nightwatch_config = {
src_folders : [ "local" ],
selenium : {
"start_process" : false,
"host" : "hub-cloud.browserstack.com",
"port" : 80
},
test_workers: {
"enabled": true,
"workers":2
},
common_capabilities: {
'browserstack.user': process.env.BROWSERSTACK_USERNAME || 'BROWSERSTACK_USERNAME',
'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY || 'BROWSERSTACK_ACCESS_KEY',
'browserstack.debug': true,
'browserstack.local': true
},
test_settings: {
default: {},
chrome: {
desiredCapabilities: {
browser: "chrome"
}
},
firefox: {
desiredCapabilities: {
browser: "firefox"
}
},
safari: {
desiredCapabilities: {
browser: "safari"
}
}
}
};
// Code to support common capabilites
for(var i in nightwatch_config.test_settings){
var config = nightwatch_config.test_settings[i];
config['selenium_host'] = nightwatch_config.selenium.host;
config['selenium_port'] = nightwatch_config.selenium.port;
config['desiredCapabilities'] = config['desiredCapabilities'] || {};
for(var j in nightwatch_config.common_capabilities){
config['desiredCapabilities'][j] = config['desiredCapabilities'][j] || nightwatch_config.common_capabilities[j];
}
}
module.exports = nightwatch_config;

Resources