How to prevent selenium to open a new chrome window on every test run? - selenium

So I'm running selenium tests with selenium-webdriver in a react project. Every time I run the tests it opens up a new chrome window, which is extremely irritating, since I end up with a million chrome windows open. Is it possible to force selenium to use the browser window already open?
EDIT:
Here's a simple example of the test code.
const webdriver = require('selenium-webdriver');
const { By, Key } = webdriver
describe('Dashboard page', () => {
it('renders correctly', async() => {
var chromeCapabilities = webdriver.Capabilities.chrome();
var chromeOptions = {
//'args': ['--headless']
};
chromeCapabilities.set('chromeOptions', chromeOptions);
const driver = new webdriver.Builder().withCapabilities(chromeCapabilities).build();
await driver.get('http://localhost:3000/dashboard')
await driver.getTitle().then((title) => {
expect(title).toEqual("My website | Dashboard")
})
await driver.getCurrentUrl().then((url) => {
expect(url).toEqual("http://localhost:3000/dashboard")
})
})
})

If you are using javascript bindings with Jasmine framework then you can try using below code. You can also refer jasmin docs for more details here
beforeEach will run only once for all tests inside a spec.js
Start browser session in beforeEach
afterEach will run once for all tests inside a spec.js
End browser session in AfterEach
describe('Before Each Spec', function () {
beforeEach(function () {
// Create new browser instance once for all spec tests
var chromeCapabilities = webdriver.Capabilities.chrome();
var chromeOptions = {
//'args': ['--headless']
};
chromeCapabilities.set('chromeOptions', chromeOptions);
const driver = new webdriver.Builder().withCapabilities(chromeCapabilities).build();
});
describe('Test Method 1', function() {
it('should have a title', function() {
// TO DO Code
});
});
describe('Test Method 2', function() {
it('should have a something to test', function() {
// TO DO Code
});
});
describe('After Each Spec', function () {
afterEach(function () {
// Destroy browser after all tests finished
browser.quit(); (or browser.driver.close();)
});
If you are using java then you can use below annotation which runs only once for complete testng xml or once per testng class e.g. #BeforeSuite or #BeforeClass
#BeforeSuite
public void setUP(){
startSeleniumSession();
}
public void startSeleniumSession(){
WebDriver driver = new ChromeDriver();
}
#Test
public void startTest2(){
driver.get("some url 1");
driver.findElement(By.id("someID")).click()
}
#Test
public void startTest2(){
// this test will run in same browser
driver.get("some url 2");
driver.findElement(By.id("someID")).click()
}
#AfterSuite
public void tearDown(){
driver.quit();
}

This settings worked for me:
options = Options()
options.add_argument('--headless')
options.add_argument('--profile-directory=Default')
browser = webdriver.Chrome(options=options,executable_path='./chromedriver/chromedriver.exe')
Key thing is to set up:
options.add_argument('--profile-directory=Default')

Related

How to share same webdriver between multiple step definition files in Selenium JS / Cucumber framework?

Unable to figure out why the following error comes up, when there is a common configuration file that serves to share webdriver among different feature files
Scenario: Amazon login # features\loginR.feature:2
Before # features\Step_Defn\cucumber.common.js:4
Given :user goes to amazon site
Undefined. Implement with the following snippet:
Given(':user goes to amazon site', function () {
Write code here that turns the phrase above into concrete actions
return 'pending';
});
Before part is invoked.Chrome pops up and closes since After is executed.But is unable to get the step definition and feature binding correct.
Following is way of invoking in VSCode
./node_modules/.bin/cucumber-js --require ./features/Step_Defn/cucumber.common.js./features/loginR.feature -f json:test/report/cucumber_report.json
the project structure is
> Selen_proj
> |
> |
> Features
> |
> Login.feature
> LoginR.feature
> |
> Step_Defn
> |
> LoginR.steps.js
> Login.steps.js
cucumber.common.js file:
require('chromedriver');
const { Before, After } = require('#cucumber/cucumber');
const webdriver = require('selenium-webdriver');
Before(() => {
global.driver = new webdriver.Builder()
.forBrowser('chrome')
.build();
})
After(() => {
driver.quit();
})
Snippet of step defn file:
require('chromedriver');
const { Given,When, Then, After } = require('#cucumber/cucumber');
const { Builder, By, until } = require('selenium-webdriver');
//let chai = require('chai');
var {setDefaultTimeout} = require('#cucumber/cucumber'); setDefaultTimeout(60 * 1000);
const { assert } = require('chai');
let driver ;
Given(':user navigates to amazon url', async function () {
driver = await new Builder().forBrowser("chrome").build();
await driver.get("https://www.amazon.com");
await driver.manage().window().maximize();
});

How to get browser console logs when using Browser library in Robotframework

I'm using Robotframework and Browser library to automate some tasks on the web. I used to use Selenium, and with selenium there is a way to get the logs, for example in the case of a failure:
driver = webdriver.Remote()
logs = driver.get_log('browser')
I've been struggling to find a way to do the same exact thing using Playwright's Browser library. Is it possible?
Certainly. You can use the page.on('console') event to log what appears in the DevTools console. Here's an example of using debug library to do so.
Make sure to export DEBUG=playwright:console or you won't see anything.
Here's how to do it in JS:
const playwright = require('playwright');
const debugConsole = require('debug')('playwright:console');
(async () => {
const browser = await playwright.chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
await page.on('console', (msg) => {
if (msg && msg.text) {
if (typeof msg.text === 'function') {
debugConsole('PAGE LOG:', msg.text());
} else {
debugConsole('PAGE LOG:', msg.text);
}
} else {
debugConsole('PAGE LOG:', msg);
}
});
await page.goto('https://example.com', { waitUntil: 'networkidle' });
})();
And in python:
from playwright.sync_api import sync_playwright
def print_args(msg):
for arg in msg.args:
print(arg.json_value())
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.on("console", print_args)
page.goto("https://abrahamjuliot.github.io/creepjs/", wait_until="networkidle")
page.wait_for_timeout(5000)
browser.close()
If you are looking for more system-level stuff, there is also a dumpio launch parameter that you can set, which will cause Playwright to provide verbose logs on the actual launch of browser executable.

Unable to open Url (.navigateTo) from .before in TestCafe using PageObjects

I am new to JS and TestCafe.
Using PageObjects in TestCafe my goal is to launch a login page and authenticate before running a test.
The .open call works fine from fixtures. Also from with .before.
fixture `Check for new emails`
.page `https://www.mail.com/myemails`
and
fixture `Check for new emails`
.page `https://www.mail.com/myemails`
.beforeEach(async t => {
console.log("before");
.page `https://www.mail.com/login`;
myloginScreen.performLogin();
})
test ('', async t => {
await t
console.log("In the test step");
});)
PageObject look like this:
import { Selector, t } from 'testcafe';
export default class LoginPage {
constructor () {
this.loginInput = Selector('input').withAttribute('id','email');
this.passwordInput = Selector('input').withAttribute('id','password');
this.signInButton = Selector('button').withAttribute('class','big-button');
this.userMenu = Selector('a').withAttribute('data-which-id', 'gn-user-menu-toggle-button');
}
async performLogin() {
console.log("function entered")
.typeText(this.loginInput, 'user#mail.com')
.typeText(this.passwordInput, 'password')
.click(this.signInButton);
console.log("Form submitted");
}
}
But I want to move the Login URL load to the PageObject like this:
async performLogin() {
console.log("function entered")
.navigateTo ("https://www.mail.com/login")
await t
.typeText(this.loginInput, 'user#mail.com')
.typeText(this.passwordInput, 'password')
.click(this.signInButton);
console.log("Form submitted");
}
The code calls the function fine but quits the .before and jumps to the test step.
I am not sure what I am doing wrong here, will appreciate any help.
The performLogin is an asynchronous method. So, you need to call it with the await keyword:
fixture `Check for new emails`
.page `https://www.mail.com/myemails`
.beforeEach(async t => {
console.log("before");
await myloginScreen.performLogin();
});

"Data;" opening with Chrome when using Selenium

I am trying to run sample code to open Google on chrome from my work desktop. However it opens with "data;" in the URL.
From what I have previously seen, this can be solved by updating the Chrome Driver.exe which I have already checked and made sure is compatible so I do not know what else the issue could be. My chrome version is 77.0.3865.90 and the driver I downloaded was 77.0.3865.40
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver_chr = new webdriver.Builder()
.forBrowser('chrome')
.build();
searchTest(driver_chr);
function searchTest(driver) {
driver.get('https//:google.ca');
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.sleep(1000).then(function () {
driver.findElement(By.name('q')).sendKeys(webdriver.Key.ENTER);
});
driver.sleep(2000).then(function () {
driver.getTitle().then(function (title) {
console.log(title)
if (title === 'Google') {
console.log('Test passed');
} else {
console.log('Test failed');
}
driver.quit();
});
});
}

How to test an Electron app with selenium webdriver

I have read the documentation and I have followed the tutorial step by step and I only have managed to run the app.
Documentation: http://electron.atom.io/docs/tutorial/using-selenium-and-webdriver/
The connection with chromedriver I cannot make it work, when I launch the test and try click a simple button I get this:
Error: ChromeDriver did not start within 5000ms at Error (native)
at node_modules/spectron/lib/chrome-driver.js:58:25 at
Request._callback (node_modules/spectron/lib/chrome-driver.js:116:45)
at Request.self.callback
(node_modules/spectron/node_modules/request/request.js:200:22) at
Request.
(node_modules/spectron/node_modules/request/request.js:1067:10) at
IncomingMessage.
(node_modules/spectron/node_modules/request/request.js:988:12) at
endReadableNT (_stream_readable.js:913:12) at _combinedTickCallback
(internal/process/next_tick.js:74:11) at process._tickCallback
(internal/process/next_tick.js:98:9)
My code:
"use strict";
require("co-mocha");
var Application = require('spectron').Application;
var assert = require('assert');
const webdriver = require('selenium-webdriver');
const driver = new webdriver.Builder()
.usingServer('http://127.0.0.1:9515')
.withCapabilities({
chromeOptions: {
binary: "./appPath/app"
}
})
.forBrowser('electron')
.build();
describe('Application launch', function () {
this.timeout(100000);
var app;
beforeEach(function () {
app = new Application({
path: "./appPath/app"
});
return app.start();
});
afterEach(function () {
if (app && app.isRunning()) {
return app.stop();
}
});
it('click a button', function* () {
yield driver.sleep(5000);
yield driver.findElement(webdriver.By.css(".classSelector")).click();
});
});
Thanks and sorry for my English.
I recommend you to use Spectron. which is a less painful way of testing your electron app. in my opinion perfect combination is using it with Ava test framework, which allows the concurrently test.
async & await is also another big win. which allows you to have so clean test cases.
and also if you have a test which needs to happen serial, you can use test.serial
test.serial('login as new user', async t => {
let app = t.context.app
app = await loginNewUser(app)
await util.screenshotCreateOrCompare(app, t, 'new-user-mission-view-empty')
})
test.serial('Can Navigate to Preference Page', async t => {
let app = t.context.app
await app.client.click('[data-test="preference-button"]')
await util.screenshotCreateOrCompare(app, t, 'new-user-preference-page-empty')
})
and just for reference; my helper test cases.
test.before(async t => {
app = util.createApp()
app = await util.waitForLoad(app, t)
})
test.beforeEach(async t => {
t.context.app = app
})
test.afterEach(async t => {
console.log('test complete')
})
// CleanUp
test.after.always(async t => {
// This runs after each test and other test hooks, even if they
failed
await app.client.localStorage('DELETE', 'user')
console.log('delete all files')
const clean = await exec('rm -rf /tmp/DesktopTest')
await clean.stdout.on('data', data => {
console.log(util.format('clean', data))
})
await app.client.close()
await app.stop()
})
util function,
// Returns a promise that resolves to a Spectron Application once the app has loaded.
// Takes a Ava test. Makes some basic assertions to verify that the app loaded correctly.
function createApp (t) {
return new Application({
path: path.join(__dirname, '..', 'node_modules', '.bin',
'electron' + (process.platform === 'win32' ? '.cmd' : '')),
// args: ['-r', path.join(__dirname, 'mocks.js'), path.join(__dirname, '..')],
env: {NODE_ENV: 'test'},
waitTimeout: 10e3
})
}
First off, Spectron (which is a wrapper for WebdriverIO) and WebdriverJS (which is part of Selenium-Webdriver) are two different frameworks, you only need to use one of them for your tests.
If you are using WebdriverJS, then you need to run ./node_modules/.bin/chromedriver in this step: http://electron.atom.io/docs/tutorial/using-selenium-and-webdriver/#start-chromedriver
I could get ChromeDriver working by adding a proxy exception in my terminal.
export {no_proxy,NO_PROXY}="127.0.0.1"