How to set the loader locale? - dojo

When I run my application in the browser, I can specify locale: 'en' as part of dojoConfig. When I run the tests in Node.js, the locale setting is the default value en. When I run the tests in a browser, the locale setting is set with the top preferred language of the browser (which is French in my case)...
I tried without success to set locale: 'en' as part of the loader configuration in my Intern config file:
return {
useLoader: { 'host-browser': 'node_modules/dojo/dojo.js' },
loader: {
locale: 'en',
packages: [{
name: 'dojo',
location: 'src/libs/dojo'
}, {
...
}
};
How can I set the locale setting for my tests running into the browsers? As I've two Intern config files, I don't mind doing something different for Node.js and for the browsers.
A+, Dom

I just hit the same issue (because dojo/_base/config.js was blowing up due to navigator.language being empty and navigator.userLanguage being undefined in my Firefox installation), and needed to get a locale set.
I ended up resorting to adding this to my testconfig.js:
if (typeof window !== 'undefined') {
// We're running inside a browser.
window.dojoConfig = window.dojoConfig || {};
window.dojoConfig.locale = window.dojoConfig.locale || "en-us";
}
Not sure whether that's 'the correct' way to do it, but it seems to be working for me with Intern 2.1.1.

Related

Playwright - Cookies not set from storageState file from different domains in Chromium

Concept
I'm using the concept of reusing the authentication state via storageState file in Playwright.
Following is my code snippet spread across different files:
Code
playwright.config.json
import type { PlaywrightTestConfig } from '#playwright/test';
import { devices } from '#playwright/test';
const config: PlaywrightTestConfig = {
testDir: './e2e',
reporter: 'html',
globalSetup: require.resolve('./e2e/global-setup.ts'),
use: {
storageState: './e2e/authStorageState.json',
},
projects: [
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
},
},
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
},
},
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
],
};
export default config;
global-setup.ts
require('dotenv').config();
import { firefox, FullConfig } from '#playwright/test';
import E2EConstants from './e2e.constants';
const authenticateUser = async () => {
const browser = await firefox.launch();
const page = await browser.newPage();
await page.goto(`${process.env.BASE_URL}/${E2EConstants.LoginPage.URL}`);
await page
.getByLabel(E2EConstants.LoginPage.LABEL.EMAIL)
.fill(process.env.TEST_ADMIN_USERNAME as string);
await page
.getByLabel(E2EConstants.LoginPage.LABEL.PASSWORD)
.fill(process.env.TEST_ADMIN_PASSWORD as string);
await page.getByText(E2EConstants.LoginPage.BUTTON).click();
await page.waitForLoadState('networkidle');
await page.context().storageState({ path: './e2e/authStorageState.json' });
await browser.close();
};
async function globalSetup(_: FullConfig) {
await authenticateUser();
}
export default globalSetup;
This sets all the cookies in the authStorageState.json file. However, some cookies have domain as .b.com and some of them have the domain as a.b.com.
example.spec.ts
require('dotenv').config();
import { test, expect } from '#playwright/test';
test('homepage has same link', async ({ page }) => {
await page.goto(process.env.TEST_URL as string);
await expect(page).toHaveURL(process.env.TEST_URL as string);
});
The TEST_URL is the URL with domain a.b.com that is behind authentication and is accessible only when the user is signed in.
Problem
When I run the tests, I see that the Chromium test fails but the Firefox and Webkit tests pass. The test is unable to sign the user in on Chromium, unlike on other browsers. This is because the auth-related cookies (belonging to a.b.com domain) are not set on Chromium but they are set on other browsers. However, the non-auth-related cookies (belonging to .b.com domain) are set properly on all browsers.
What I tried
I tried manually setting the url of the cookies saved in authStorageState.json file to https://a.b.com after deleting the domain and path keys for the auth-related cookies and then when I run the tests, the Chromium test also passes.
The secure key for all cookies, which were not set, had the value as false. I tried manually changing the "secure": true for all cookies which were not set. Note that the sameSite property is set to "None". This change made the Chromium test cases to pass.
The sameSite key for all cookies, which were not set, had the value "None" while having "secure": false property. I tried manually removing the "sameSite": "None" property for all cookies which were not set. Note that I did not change the secure property. This change made the Chromium test cases to pass.
[Note that all the above points were independently implemented as workarounds and were not done together.]
Requirement
However, because the authStorageState.json file is to be created by default on first sign-in, I want to persist the same cookies that appear on browser instead of manually manipulating them. How can I get my Chromium test cases to pass?
Doubts
What is the difference between providing url instead of domain + path for Chromium?
Why do the cookies with subdomain a.b.com require secure property to be set to true and the Chromium-based test cases pass after this change?
Is removing the "sameSite": "None" for all the cookies with subdomain a.b.com right and why do the Chromium-based test cases pass after this change?

Running tests with flags from chrome cypress

I have some test cases that use webcam and our test enviroment needs for using webcam to have set flag in chrome --unsafely-treat-insecure-origin-as-secure
How can I for some test sets have this set in chrome with cypress?
Thanks
You can pass flags to the chrome browser in Cypress by writing a Cypress plugin as seen in the official documentation here: https://docs.cypress.io/api/plugins/browser-launch-api.html#Usage.
Navigate to your cypress/plugins directory and add the following code
module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, launchOptions) => {
// `args` is an array of all the arguments that will
// be passed to browsers when it launches
if (browser.name === 'chrome') {
launchOptions.args.push('--unsafely-treat-insecure-origin-as-secure');
}
// whatever you return here becomes the launchOptions
return launchOptions;
});
};

How to be more verbose on tests?

I wanted to have more verbose output for each test step;
Any ideas on how could I best achieve this without adding console.log after each step ?
I tried to overload the t object as shown below but can't get to have it work more than one time in the output.
in mylib.js
exports.init = function(t) {
t.oTypeText = t.typeText;
t.typeText = function fn(selector, data, opts) {
console.log('typing text in '+selector+': '+data);
return t.oTypeText(selector, data, opts);
};
return;
};
in test.js
import { Selector } from 'testcafe';
const mylib = require('./mylib');
fixture("Getting Started")
.page("https://devexpress.github.io/testcafe/example");
test('My first test', async t => {
mylib.init(t);
await t.typeText('#developer-name', 'John Smith')
.selectText('#developer-name').pressKey('delete')
.typeText('#developer-name', 'new name')
.selectText('#developer-name').pressKey('delete')
.typeText('#developer-name', 'another name');
await t.click('#submit-button');
});
result is:
Using locally installed version of TestCafe.
Running tests in:
- Firefox 68.0.0 / Mac OS X 10.14.0
Getting Started
(node:62978) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
typing text in #developer-name: John Smith
✓ My first test
1 passed (4s)
TestCafe doesn't support this feature out of box. I've created suggestion for you use case - https://github.com/DevExpress/testcafe/issues/4001 in the TestCafe repository. We can use the way with action overriding right now, but theoretically it can broke some functionality.

how to repeat same test suite for multiple time with different url

I have a webapp which supports multiple language
based on the query params it loads in different lang
for ex : http://eeee.com/home?lang=US will load in english and http://eeee.com/home?lang=french
I have automation code written for english
I need to run the same code for all other language as well
something like
"test-english": "./node_modules/.bin/wdio wdio.conf.js --lang=US"
should run for english
"test-french": "./node_modules/.bin/wdio wdio.conf.js --lang=fr"
should run for french
or atleast first it should run all test for english and then for french
my wdio.conf.js
looks like
exports.config = {
specs: [
'./test/**/*.test.js'
],
baseUrl: 'http://eeee.com/',
}
Inorder to have custom option in wdio we can use something like this in wdio.conf.js
onPrepare: function(config, capabilities) {
if (process.argv !== undefined && process.argv.length) {
process.argv.forEach(arg => {
if (arg.indexOf('--lang=') !== -1) {
process.env.lang = arg.replace('--lang=', '');
}
});
}
},
before: function(capabilities, specs) {
global.lang = process.env.lang;
}

intern dojo loader issue

I'm trying to setup intern for my project, a Dojo/JS project, and the server is not Node... I get a loader issue, which seems to be due to dojo.has using Dojo loader... The require wrapper suggested in here did not work for me.
I get the error below:
> node node_modules/intern/client.js config=tests/intern
Defaulting to "console" reporter
dojo/text plugin failed to load because loader does not support getText
TypeError: undefined is not a function
at Object.load (lib/dojo/dojo/text.js:199:6)
Below are my intern configuration and the test file:
/tests/intern.js: (config file)
loader: {
packages: [ { name: 'visitorsPortal', location: 'portals/visitor' },
{ name: 'dojo', location: 'lib/dojo/dojo'},
{ name: 'dijit', location: 'lib/dojo/dijit'},
{ name: 'portalLib', location: 'portals/lib'} ]
},
suites: [ 'tests/uitests' ],
tests/uitests:
define([
'intern!tdd',
'intern/chai!assert',
'portals/visitor/views/MyModule'
], function (test, assert, MyModule) {
// empty for now...
});
This has nothing to do with dojo/has and everything to do with the dojo/text plugin requiring functionality that only exists within the Dojo 1 loader when being used server-side.
If you are attempting to test software that relies on any non-standard AMD loader functionality, you will need to use the non-standard loader, or override those modules with alternative copies that are compatible with other loaders.
In this specific case, your easiest path forward is to use the geezer edition of Intern, since it includes the old Dojo loader which contains these non-standard extensions. The best path forward is to remap the dojo/text module to another compatible module that does not need anything special in the loader in order to retrieve the data:
// in intern.js
// ...
loader: {
map: {
'*': {
'dojo/text': 'my/text'
}
}
},
// ...
I struggled with the same problem yesterday, but thanks to C Snover's answer here and the question you're linking to, I did make some progress.
I added the map directive to the intern.js loader config (as C Snover suggests).
// in intern.js
// ...
loader: {
map: {
'*': {
'dojo/text': 'my/text'
}
}
},
// ...
For the my/text module, I just copied dojo/text and added an else if clause to the part that resolves the getText function:
if(has("host-browser")){
getText= function(url, sync, load){
request(url, {sync:!!sync}).then(load);
};
} else if(has("host-node")){
// This was my addition...
getText = function(url, sync, load) {
require(["dojo/node!fs"], function(fs) {
fs.readFile(url, 'utf-8', function(err, data) {
if(err) console.error("Failed to read file", url);
load(data);
});
});
};
} else {
// Path for node.js and rhino, to load from local file system.
// TODO: use node.js native methods rather than depending on a require.getText() method to exist.
if(require.getText){
getText= require.getText;
}else{
console.error("dojo/text plugin failed to load because loader does not support getText");
}
}
However, even though the tests were running in intern via node, the host-node value wasn't being set. That was fixed by setting dojo-has-api in my intern.js config:
define(["intern/node_modules/dojo/has"], function(has) {
has.add("dojo-has-api", true);
return { /* my intern config as normal */ };
});
I'll admit I don't understand 100% what I've done here, and with the copy/pasting it's not exactly pretty, but it serves as a temporary fix for my problem at least.
Note: This did introduce another set of issues though: Since Dojo now knows that it's running in node, dojo/request no longer tries to use XHR. I was using sinon.js to mock my xhr requests, so this had to be changed.