"Data;" opening with Chrome when using Selenium - 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();
});
});
}

Related

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.

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

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')

Error : profile.getTemplateDir is not a function

I'm trying to implement a multi-browser test with protractor with firefox and chrome. But for the test, I need to change the download path. In chrome, it works but in firefox, the solution I found involved changing the profile of firefox. I also found a way to do it as in the answers of this question Set firefox profile protractor .
But when I try to run multiple instance of navigator alongside of one instance of firefox with modified profile, I always get an error as profile.getTemplateDir is not a function.
Here is the code in my protractor configuration file :
var q = require('q');
var FirefoxProfile = require("selenium-webdriver/firefox").Profile
function getProfiles() {
let deferred = q.defer();
let multiCapabilities = [{
browserName: 'chrome'
}]
deferred.resolve(multiCapabilities);
let firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference("browser.download.folderList", 2);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
firefoxProfile.setPreference("browser.download.dir", '/tmp');
let foxCapabilities = {
browserName: 'firefox',
firefox_profile: firefoxProfile
};
multiCapabilities.push(foxCapabilities);
deferred.resolve(multiCapabilities);
return deferred.promise;
}
exports.config = {
seleniumAddress: "http://localhost:4444/wd/hub",
specs: [
'spec.js'
],
framework: 'jasmine2',
getMultiCapabilities: getProfiles,
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
},
};
Does anyone knows why this error is triggered and how to resolve it ?
Thanks
So I have digged into this issue debugging the code and this seems to be limitation/bug currently in selenium web-driver
When getMultiCapabilities returns multiple browsers, then protractor creates a fork of the process to run the test
This forked process is then sent the profile you created as JSON
The childprocess can only receive JSON data in form of text and not in form of a Profile object
Later createGeckodriver function is called with profile object. But as the code of createGeckodriver it is always expecting a profile object
So this code needs to be fixed in Selenium webdriver itself and it should check if the profile sent is already encoded or not. Also the code you have used needs to be fixed to encode the profile. Below is what would work once Selenium driver is patched to allow sending encoded profile
var firefox = require('selenium-webdriver/firefox');
var q = require('q');
var FirefoxProfile = require("selenium-webdriver/firefox").Profile
var makeFirefoxProfile = function (preferenceMap) {
var deferred = q.defer();
var firefoxProfile = new FirefoxProfile();
for (var key in preferenceMap) {
firefoxProfile.setPreference(key, preferenceMap[key]);
}
firefoxProfile.encode().then(function(encodedProfile){
cap = {
"browserName": "firefox",
marionette: true,
"firefox_profile": encodedProfile,
};
deferred.resolve(cap);
});
return deferred.promise;
};
exports.config = {
seleniumAddress: "http://localhost:4444/wd/hub",
specs: [
'spec.js'
],
framework: 'jasmine',
getMultiCapabilities: function () {
return q.all([
{
browserName: 'chrome'
},
makeFirefoxProfile(
{
"browser.download.folderList": 2,
"browser.download.dir": "/path/to/save/downloads",
"browser.helperApps.neverAsk.saveToDisk": "application/zip"
}
)
]);
},
jasmineNodeOpts: {
defaultTimeoutInterval: 180000
}
};

How to override the preconfigured casper instance in a test environment

i have installed the phantomjs 1.9.7 & casperjs 1.1.0 and now i see that all my scripts need to be updated and to remove the first line since it makes the below fatal error:
Fatal: you can't override the preconfigured casper instance in a test environment.
Docs: http://docs.casperjs.org/en/latest/testing.html#test-command-args-and-options
Reading also in another question i understand that i have to remove now this line from my scripts:
var casper = require('casper').create();
Which is a lot of work since i have meanwhile more then 200 script that needs to be updated!!!
So my question is how can i overcome this issue without updating all the scripts (mentioned in Can't run the testing framework in CasperJS)
var casper = require('casper').create();
if (casper.cli.has("ip") === false) {
casper.echo("Usage: casper.js test get_info.js --ip=<x.x.x.x>").exit();
}
casper.test.begin('get info', 1, function suite(test) {
casper.start("http://" + casper.cli.get("ip") + ":xxxx/man/", function() {
test.assertTitle("TEST GUI", "GUI has the correct title");
test.assertExists('form[name="loginForm"]', "login form is found");
this.fill('form[name="loginForm"]', {
'userId': 'xxxxx',
'password': 'yyyyy'
}, true);
});
casper.then(function() {
test.assertTextExists("Welcome", "Login into TEST GUI");
this.click('a#test_menu.menu1itemUnSel[tabindex="4"]');
});
casper.then(function() {
casper.wait(5000, function() {
this.echo('should appear after 5s');
});
});
casper.then(function() {
test.assertTextExists("TEST Data", "Login into Data");
this.click('a#test_menu_data.menu2itemUnSel[tabindex="4"]');
});
casper.then(function() {
casper.wait(5000, function() {
this.echo('should appear after 5s');
});
});
casper.then(function() {
test.assertTextExists("Logout", "Loggin out from TEST GUI");
this.click('a.minorLinkshighlight');
});
casper.run(function() {
test.done();
this.exit();
});
});
The above script was working before i installed the phantomjs 1.9.7 & casperjs 1.1.0, the only thing that i can't recall is which version i had before my server had to be reinstalled!
Thanks in adv.
Yes this is my way of avoiding updating old casperjs scripts due to the overriding of the preconfigured casper instance in a test environment!
go to the casperjs path and edit in path modules:
/../casperjs/modules/casper.js
and remark out the below lines:
exports.create = function create(options) {
"use strict";
// This is a bit of a hack to check if one is trying to override the preconfigured
// casper instance from within a test environment.
// if (phantom.casperTest && window.casper) {
// console.error("Fatal: you can't override the preconfigured casper instance in a test environment.");
// console.error("Docs: http://docs.casperjs.org/en/latest/testing.html#test-command-args-and-options");
// phantom.exit(1);
// }
return new Casper(options);
};
This worked for me. You should use it only on your own risk!

Exposing variables from PhantomJS call to injectJS

I've followed examples for injecting jQuery from the getting started page and that works just fine. I have a local copy of jQuery in the same directory, and do something like...
if(page.injectJs('jquery.min.js')) {
page.evaluate(function(){
//Use jQuery or $
}
}
When I try to inject my own script(s), none of the functions are available to me. Say I have a script called myScript.js that just has
function doSomething() {
// doing something...
}
I cannot then use doSomething like...
if(page.injectJs('myScript.js')) {
console.log('myScript injected... I think');
page.evaluate(function() {
doSomething();
});
} else {
console.log('Failed to inject myScript');
}
I've tried
window.doSomething = function() {};
and
document.doSomething = function() {};
as well with no luck, as well as trying to call them with window.doSomething() or document.doSomething() in the subsequent page.evaluate().
The following works for me, maybe some other part of your app logic is wrong:
inject.coffee
page = require('webpage').create()
page.onConsoleMessage = (msg) -> console.log msg
page.open "http://www.phantomjs.org", (status) ->
if status is "success"
page.includeJs "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js", ->
if page.injectJs "do.js"
page.evaluate ->
title = echoAndReturnTitle('hello')
console.log title
phantom.exit()
do.coffee:
window.echoAndReturnTitle = (arg) ->
console.log "echoing '#{arg}'"
console.log $(".explanation").text()
return document.title
Result:
> phantomjs inject.coffee
echoing 'hello'
PhantomJS is a headless WebKit with JavaScript API.
It has fast and native support for various web standards:
DOM handling, CSS selector, JSON, Canvas, and SVG.
PhantomJS is created by Ariya Hidayat.
PhantomJS: Headless WebKit with JavaScript API
or if you prefer JavaScript (they're auto-generated and a little ugly):
`inject.js':
// Generated by CoffeeScript 1.3.1
(function() {
var page;
page = require('webpage').create();
page.onConsoleMessage = function(msg) {
return console.log(msg);
};
page.open("http://www.phantomjs.org", function(status) {
if (status === "success") {
return page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js", function() {
if (page.injectJs("do.js")) {
page.evaluate(function() {
var title;
title = echoAndReturnTitle('hello');
return console.log(title);
});
return phantom.exit();
}
});
}
});
}).call(this);
do.js:
// Generated by CoffeeScript 1.3.1
(function() {
window.echoAndReturnTitle = function(arg) {
console.log("echoing '" + arg + "'");
console.log($(".explanation").text());
return document.title;
};
}).call(this);