How i can to customize testRunner from testcafe framework? - testing

I have my testRunner for tests.
But the problem is -> how i can add the browser resolution in test
runner, because i don't want to add this to my tests.
Thanks for help.
runner
.src(testFiles)
.browsers('chrome')
.reporter('html', stream)
.run()
.then(failedCount => {
console.log(failedCount);
testcafe.close();

You can manage the resolution of your browser via cmd parameters. Since Chrome supports --window-size parameter you can pass it to the .browsers method of your runner.
Please see the following example:
const createTestCafe = require('testcafe');
let testcafe = null;
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc;
const runner = testcafe.createRunner();
return runner
.src('my-tests.js')
.browsers(['chrome --window-size=1000,500', 'chrome --window-size=500,200'])
.run();
})
.then(failedCount => {
console.log('Tests failed: ' + failedCount);
testcafe.close();
});
Here I run tests in two Chrome instances but with different window sizes
Please also refer to the following article https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#browsers to see different ways of using the .browsers method

Related

How do we use expect in WebdriverIO as a standalone script?

WebdriverIO has a sample of using it in a script:
https://webdriver.io/docs/gettingstarted#run-in-a-script
const { remote } = require('webdriverio');
;(async () => {
const browser = await remote({
capabilities: {
browserName: 'chrome'
}
})
await browser.url('https://webdriver.io')
const apiLink = await browser.$('=API')
await apiLink.click()
await browser.saveScreenshot('./screenshot.png')
await browser.deleteSession()
})()
However, there is no mentioning of how we can use expect, such as expect(elementFoo).toHaveText("Hello World") How can we have expect (and have one of mocha, jasmine, or cucumber like when we set up a webdriverio project using
npx wdio ./path/to/new/project
or is it already possible to use expect without using one of those three modules?)
Also, if we used npx wdio ./path/to/new/project to create a whole project, the expect(elementFoo).toHaveText("Hello World") knows how to wait a few seconds to finally say that it doesn't contain the text, which I am not sure if pure mocha, jasmine, or cucumber has that feature too.

How do I run tests on multiple browsers in lambdatest?

I have a lambdatest and testcafe setup, lambdatest account has a single parallel run.
As far as I understand, testcafe doesn't support queuing of tests.
So my question is how do I manage to run tests on different browser/OS combination on lambdatest(one after the other without queuing).
Thanks in advance.
You can create several runners for each browser and run them in series. You can find an example in the following thread on GitHub:
https://github.com/DevExpress/testcafe/issues/2495#issuecomment-421090352
As Dmitry stated, you can create several runners for each browser and run them in series.
Here is an example code to run parallel testing over LambdaTest Selenium Grid through custom testcafe runner.
const browsers = [
['lambdatest:Chrome#74.0:Windows 10"', 'lambdatest:Chrome#75.0:Windows 10'],
['lambdatest:Chrome#76.0:Windows 8', 'lambdatest:Chrome#77.0:Windows 8'],
];
const runTest = async browser => {
console.log('starting tests');
await createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc;
const runner = testcafe.createRunner();
return runner
.src(['web-tests/*.ts'])
.browsers(browser)
.run();
})
.then(async failedCount => {
console.log('Tests failed: ' + failedCount);
await testcafe.close();
return;
});
}
const runAllBrowsers = async () => {
for (const browser of browsers) {
await runTest(browser);
}
}
For more information, refer to GitHub repository of LambdaTest & Testcafe. Cheers!

Is there a way to specify a dynamic report filename in TestCafe

I am writing the output of my TestCafe to file. I was wondering if it can be a dynamic path like a screenshot path.
I tried using something like the values listed here, but I think this is only for screenshots and videos.
https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/screenshots-and-videos.html#path-pattern-placeholders
Here is what works, but is just not dynamic:
testcafe chrome test.testcafe -r json:report.json
Here is what I would like to do:
testcafe chrome test.testcafe -r json:T:\Logs\ -p ${DATE}/${TIME}/${FIXTURE}/${TEST}/${FILE_INDEX}.json
EDIT 1: Should have said this, but I am using TestCafe Studio. I can use the built-in Function action, but I'm stuck with the limited functionality of Studio.
I suggest you use the programming interface to customize your reporter output:
run.js:
const createTestCafe = require('testcafe');
let testcafe = null;
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc;
const runner = testcafe.createRunner();
const config = { key1: 'value1', key2: 'value2' }; // you can specify it as a date, etc.
return runner
.src(['d:/***/test.js'])
.browsers(['chrome'])
.reporter('xunit', `reports/${config.key1}/out-${config.key2}.xml`)
.run();
})
.then(failedCount => {
console.log('Tests failed: ' + failedCount);
testcafe.close();
});
Command:
node run.js
Currently, TestCafe Studio does not allow customizing a report name. We will consider your suggestion for our future releases.
As a workaround, I recommend you take a look at the Export the Report functionality

How to make testcafe wait until a fixture is done executing before moving to the next fixture when using concurrency?

I want to run testcafe tests concurrently BUT only executing against 1 file at a time.
In other words, I want to wait for all the tests of a specific fixture to be done executing before the tests from the next fixture start executing.
How do I do it?
You can do this using the TestCafe programming interface.
Please see the following example:
const createTestCafe = require('testcafe');
let testcafe = null;
let runner = null;
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc;
runner = tc.createRunner()
.browsers('chrome')
.concurrency(3);
})
.then(() => {
return runner.src('fixture1.js').run();
})
.then(() => {
return runner.src('fixture2.js').run();
})
.then(() => {
testcafe.close();
});
However, please note that I run tests twice in sequence here. That means that your browsers will be opened twice too. You will also get two different reports.

TestCafe 'dynamic' tests cases

I created a few e2e sanity tests for my current project using TestCafe. These tests are standard TestCafe tests:
fixture(`Basic checkout flow`)
test('Main Flow', async (t) => {
});
I would like to execute this test for multiple site locales and for multiple channels. i.e. I need this test to run for nl_nl, nl_be, en_gb, .. and also for channels like b2c, b2b, ...
The easiest way is to create a loop in the test itself to loop over the locales and channels, but I want to run these test concurrently.
I tried to create a function to dynamically generate these tests, but TestCafe can't seem to detect the tests then.
dynamicTest('Main Flow', async (t) => {
});
function dynamicTest(testName, testFn) => {
const channels = ['b2c']
channels.forEach((channel) => {
test(`[Channel] ${channel}] ${testName}`, testFn);
});
};
Is there a better way of doing this? The only solution I see is running the test script multiple times from Jenkins to have concurrency.
more detailed code:
import HomePage from '../../page/HomePage/HomePage';
import EnvUtil from '../../util/EnvUtil';
const wrapper = (config, testFn) => {
config.locales.forEach(async locale =>
config.channels.forEach(async channel => {
const tstConfig = {
locale,
channel
};
tstConfig.env = EnvUtil.parse(tstConfig, config.args.env);
testConfig.foo = await EnvUtil.get() // If I remove this line it works!
testFn(config, locale, channel)
})
);
};
fixture(`[Feature] Feature 1`)
.beforeEach(async t => {
t.ctx.pages = {
home: new HomePage(),
... more pages here
};
});
wrapper(global.config, (testConfig, locale, channel) => {
test
.before(async (t) => {
t.ctx.config = testConfig;
})
.page(`foo.bar.com`)
(`[Feature] [Locale: ${locale.key}] [Channel: ${channel.key}] Feature 1`, async (t) => {
await t.ctx.pages.home.header.search(t, '3301');
.. more test code here
});
});
If I run it like this I get a "test is undefined" error. Is there something wrong in the way I'm wrapping "test"?
Using TestCafe of version 0.23.1, you can run tests imported from external libraries or generated dynamically even if the test file you provide does not contain any tests.
You can learn more here: Run Dynamically Loaded Tests