how to Implemented zoom out in my automation test? - javascript

i wanna ask. i got problem when i implemented the zoom out in my testing code. the example code like this
describe('demoqa web testing', () => {
beforeEach(async function(){
await browser.maximizeWindow();
});
it('form testing', async() => {
await browser.url("https://demoqa.com/automation-practice-form");
await browser.execute(() => {
return document.body.style.zoom = '50%';
});
})
})
I'm using webdriverIO and the problem is, when i run npx wdio. the browser can't be zoom out until 50%. maybe do you have some advice on my code? thank you
so, i'm expecting when i run the test, and then the browser already zoom out

Related

Is it possible to create custom commands in Playwright?

I'm looking for a way to write custom commands in Playwright like it's done in Cypress. Playwright Issues has one page related to it but I have never seen any code example.
I'm working on one test case where I'm trying to improve code reusability. Here's the code:
import { test, chromium } from '#playwright/test';
config();
let context;
let page;
test.beforeEach(async () => {
context = await chromium.launchPersistentContext(
'C:\\Users\\User\\AppData\\Local\\Microsoft\\Edge\\User Data\\Default',
{
headless: false,
executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
}
);
page = await context.newPage();
await page.goto('http://localhost:3000/');
});
test.afterEach(async () => {
await page.close();
await context.close();
});
test('Sample test', async () => {
await page.click('text=Open popup');
await page.click('_react=Button >> nth=0');
await page.click('text=Close popup');
});
I'm trying to create a function that will call hooks test.beforeEach() and test.afterEach() and the code inside them.
In the Playwright Issue page, it says that I need to move it to a separate Node module and then I would be able to use it but I'm struggling to understand how to do it.
The example you're giving can be solved by implementing a custom fixture.
Fixtures are #playwright/test's solution to customizing/extending the test framework. You can define your own objects (similar to browser, context, page) that you inject into your test, so the test has access to it. But they can also do things before and after each test such as setting up preconditions and tearing them down. You can also override existing fixtures.
For more information including examples have a look here:
https://playwright.dev/docs/test-fixtures

Does Jest run test suites defined with describe() asynchronously?

Summary of problem: I'm writing several test suites (using Jest and Puppeteer) to automate tests for my AngularJS app's index.html page. Unfortunately, I'm seeing some odd behavior when I run my tests, which I think is related to the order in which Jest runs my various test suites.
Background: I'm using Jest (v24.8.0) as my testing framework. I'm using Puppeteer (v1.19.0) to spin up and control a Chromium browser on which to perform my tests.
My Code:
<!-- index.html -->
<div ng-app="myApp" ng-controller="myCtrl as ctrl">
<form name="form1">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name1"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
<form name="form2">
<md-input-container>
<label class="md-required">Name</label>
<input ng-model="ctrl.name2"></input>
</md-input-container>
<md-dialog-actions>
<button class="md-primary md-button" ng-transclude type="submit">Submit</button>
</md-dialog-actions>
</form>
</div>
// index.spec.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://my-site.com');
describe('form 1', async () => {
test('populate form 1', async () => {
let formSelector = 'form[name="form1"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('casey');
let submitButtonSelector = 'form[name="form1"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
describe('form 2', async () => {
test('populate form 2', async () => {
let formSelector = 'form[name="form2"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('jackie');
let submitButtonSelector = 'form[name="form2"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
await browser.close();
})();
Test Behavior:
Sometimes when I run npm test it seems that my two test suites, 'form1' and 'form2' (which I defined with describe), are being run in parallel (although I know that's not possible in Javascript, so I am assuming Jest runs different test suites asynchronously). Either way, when I run my tests in non-headless mode, I can see that form1's name input is populated with 'jackie', even though it should be 'casey'. After that happens, form2 is never filled out (even though my second test suite is supposed to do just that) and the tests complete, after which Jest informs me that 'populate form 2' has failed. Again, this doesn't happen every time I run my tests, so you may not be able to replicate my problem.
My Questions:
Does Jest run test suites in parallel/asynchronously? Note: I'm not talking about individual test's defined with test within the test suites, I know that those are run asynchronously if I pass them an async function.
If Jest does run test suites asynchronously, how do I disable that? Or better yet, is smart/conventional/optimal to give different test suites different browser instances so that they are run in completely separate windows? Are there any other methods for ensuring test suites are run separately and/or synchronously?
If Jest does not run test suites asynchronously, then why do you think I'm seeing this behavior?
I'm asking because I'd like to find a way to ensure that all my tests pass all of the time, instead of just some of the time. This will make it easier in the long run to determine whether or not my changes during development have broken anything.
Thanks in advance to all you Jest/Puppeteer hackers out there!
By default Jest runs tests in each file concurrently depending on max workers, but runs all describe and tests blocks serially within a file.
If you want all all files run serially use run in band, this removes the workers pool.
However, i recommend refactor, you can nest describe blocks
// instead of IIFE, nest describes for better parsing for jest and readability
describe('forms', async () => {
const browser = await puppeteer.launch({headless: false});
describe('form 1', () => {
test('populate form 1', async () => {
// make every test independent of the other to avoid leaky scenarios
const page = await browser.newPage();
await page.goto('https://my-site.com');
let formSelector = 'form[name="form1"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('casey');
let submitButtonSelector = 'form[name="form1"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
describe('form 2', () => {
test('populate form 2', async () => {
const page = await browser.newPage();
await page.goto('https://my-site.com');
let formSelector = 'form[name="form2"]';
await page.waitForSelector(formSelector+' input', {timeout: 3000});
await page.click(formSelector+' input');
await page.keyboard.type('jackie');
let submitButtonSelector = 'form[name="form2"] button[type="submit"]';
await page.click(submitButtonSelector);
});
});
await browser.close();
})
Update
In NodeJS you can spawn processes , in the case of jest, each process is a node instance and they communicate through standard IO. You can tell jest how many to spawn with the CLI options, however, i've encounter performance degradation when using slightly many workers with jest, due the fact that NodeJS instances are heavyweight, and spawn/sync might be more costly than actually just running in band or few workers.
Also, there is no garante on how they run, if you want to spawn 10 processes, your OS might schedule all to the same CPU thread, and they would be running in series.

I need close and open new browser in protractor

I have a simple test:
beforeEach(function () {
lib.startApp(constants.ENVIRONMENT, browser);//get url
loginPageLoc.loginAs(constants.ADMIN_LOGIN,constants.ADMIN_PASSWORD,
browser);// log in
browser.driver.sleep(5000); //wait
});
afterEach(function() {
browser.restart(); //or browser.close()
});
it('Test1' , async() => {
lib.waitUntilClickable(adminManagersPage.ButtonManagers, browser);
adminManagersPage.ButtonManagers.click();
expect(element(by.css('.common-popup')).isPresent()).toBe(false);
});
it('Test2' , async() => {
lib.waitUntilClickable(adminManagersPage.ButtonManagers, browser);
adminManagersPage.ButtonManagers.click();
expect(element(by.css('.common-popup')).isPresent()).toBe(false);
});
The first iteration looks fine, but after .restart() I get:
Failed: This driver instance does not have a valid session ID (did you
call WebDriver.quit()?) and may no longer be used. NoSuchSessionError:
This driver instance does not have a valid session ID (did you call
WebDriver.quit()?) and may no longer be used.
If I use .close() I get:
Failed: invalid session id
But if I change Test2 on simple console.log('case 1'); it looks fine.
Please explain what am I doing wrong?
You are declaring your functions as async but are not awaiting the any actions within. If you are not setting your SELENIUM_PROMISE_MANAGER to false in your config then you will see unexpected behavior throughout your test when declaring async functions. This async behavior is likely the cause of your issue so I would ensure SELENIUM_PROMISE_MANAGER:false and ensure your awaiting your actions in each function.
The reason your test passes if you change the second test to just be console.log() is because you are not interacting with the browser and therefore the selenium session ID is not required. Every time the browser is closed the selenium session id will be destroyed and a new one created when a new browser window is launched.
Also you should be aware that there is a config setting you can enable so you do not need to do it manually in your test.
Update: Adding code examples of what I have described:
Note: If you have a lot of code already developed it will take serious effort to convert your framework to Async/await syntax. For a quicker solution you could try removing the async keywords from your it blocks
Add these to your config
SELENIUM_PROMISE_MANAGER:false,
restartBrowserBetweenTests:true
and change you spec to
beforeEach(async function () {
await lib.startApp(constants.ENVIRONMENT, browser);//get url
await loginPageLoc.loginAs(constants.ADMIN_LOGIN, constants.ADMIN_PASSWORD,
browser);// log in
await browser.driver.sleep(5000); //wait
});
it('Test1', async () => {
await lib.waitUntilClickable(adminManagersPage.ButtonManagers, browser);
await adminManagersPage.ButtonManagers.click();
expect(await element(by.css('.common-popup')).isPresent()).toBe(false);
});
it('Test2', async () => {
await lib.waitUntilClickable(adminManagersPage.ButtonManagers, browser);
await adminManagersPage.ButtonManagers.click();
expect(await element(by.css('.common-popup')).isPresent()).toBe(false);
});
There is a relevant configuration option:
// If true, protractor will restart the browser between each test.
restartBrowserBetweenTests: true,
Add the above in your config to restart browser between your tests.
Hope it helps you.

Nightwatch - Determine if tests have passed or failed

I'm trying to integrate my test suite with Saucelabs and to determine if the tests have passed or failed I need to do this myself.
Here is the code for the test that I have (notice I'm using Mocha):
describe('Smoke Test', () => {
describe('Login', () => {
it('Should login', (client) => {
pages.login(client).validLogin(client.globals.users.SMOKE.USERNAME, client.globals.users.SMOKE.PASSWORD);
});
});
after((client, done) => {
client.end(() => {
done();
});
});
});
Is it possible in the after block to know if the test have passed or failed?
From some examples that I found, including Saucelabs example I've seen this line:
client.currentTest.results
However currentTest have only name and method attributes.
Well, this might be late reply for you. Hope this is useful for other viewers.
afterEach will have results. Add afterEach to your example.
Apart from this, you can also get results in runner itself. Explore 'reporter' file in mocha-nightwatch. It is in your node_modules.
..\node_modules\mocha-nightwatch\lib\reporters\json.js
There are events like
runner.on(start ..)
and
runner.on(end..)
these will trigger for each tests. Give a try.

close browser session after failed assertion with nightwatch

I implement a new testframework for automated tests in node.js with Nightwatch-Cucumber that based on Nightwatch.js. So, sometimes I use node.js Assertions to check some values. I work with the PageObject Pattern in my framework. My problem is that the browser session doen't close after a failed assertion and I don't know why and I don't know how to solve the problem.
Here is my StepDefinition:
const {
client
} = require('nightwatch-cucumber');
const {
defineSupportCode
} = require('cucumber');
const page = client.page.page();
defineSupportCode(({Given, When, Then}) => {
When(/^test$/, () => {
return page.test();
});
});
And that's my PageObject function:
module.exports = {
elements: {},
commands: [{
test() {
//here the assertion failed and the browser session still exist and doen't close
this.assert.equal(false, true);
return this.api;
}
}]
};
So, what can I do to realize it to close the browser and the session for ths test? It happened only if the node.js assertions fail.
Use an after or afterEach hook to always close the browser at the end of a test, regardless of outcome. See http://nightwatchjs.org/guide#using-before-each-and-after-each-hooks
after : function(browser) {
console.log('Closing down...');
browser.end();
},
To close your session after each test you have to add afterEach hook to your test file and use it like this:
afterEach : function(browser, done) {
browser.end(function(){
done();
});
}

Categories

Resources