Is the Firefox Web Console accessible in headless mode? - javascript

The title says it all: I am wondering whether it is possible to interact with the Firefox console upon starting Firefox in headless mode.
More generally, I'd settle for some way of accessing it programmatically, in scripts.
What I've tried:
So far I've been playing with the Javascript bindings to Selenium without success:
Starting Firefox with the -devtools option from Selenium does opn the dev tools, but I then cannot send key combinations that will switch me to the actual console, or in fact interact from my .js script with the open devtools window in any way.
Edit
In response to the first comment below: this answer does not seem to help. The console is not opened when I send CTRL+SHIFT+k to the body tag of google.com:
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var firefox = require('selenium-webdriver/firefox');
var inpt = require('selenium-webdriver/lib/input');
var options = new firefox.Options();
var driver = new webdriver.Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
.build();
(async function(){
await driver.get('https://google.com');
var bdy = await driver.findElement(By.id('gsr'));
await bdy.sendKeys(inpt.Key.CONTROL + inpt.Key.SHIFT + 'k');
})();
This opens the page (google.com) and returns no errors, but there's no console anywhere.
For good measure: sending just inpt.Key.SHIFT + 'k' does enter a capital 'K' in the Google search field, so I know the keys are referenced correctly.
Also, sending just 'k' enters a small 'k' in the search field. It's only the three-key combo that does not work.
2nd edit:
I take it back: the newer answer does work, precisely as-is (I switched to Python from node).

The comment below by Karthik does resolve the matter, but I would like to summarize here and document working solutions that automate Firefox-Web-Console access.
The point of the answer I linked to above (in my 2nd edit) is that in order to have full access to the Firefox browser key controls one must
first switch Firefox context to chrome (from the default content context)
direct the automated browser driver to locate the element carrying id tabbrowser-tabs
send the key combo (in this case Ctrl+Shift+k) to that element.
Concrete working solutions:
Python
The script is
from selenium.webdriver import Firefox, DesiredCapabilities, FirefoxProfile
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.keys import Keys
import time
options = Options()
webdriver = Firefox(options=options)
webdriver.get("https://google.com")
try:
time.sleep(3)
with webdriver.context(webdriver.CONTEXT_CHROME):
console = webdriver.find_element(By.ID, "tabbrowser-tabs")
console.send_keys(Keys.LEFT_CONTROL + Keys.LEFT_SHIFT + 'k')
except:
pass
Run with python <path-to-script> it opens a Firefox window displaying google.com and the console at the bottom.
Javascript
Here the full script is
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var firefox = require('selenium-webdriver/firefox');
var inpt = require('selenium-webdriver/lib/input');
var options = new firefox.Options();
var driver = new webdriver.Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
.build();
(async function(){
await driver.get('https://google.com');
await driver.setContext("chrome");
var tabs = await driver.findElement(By.id('tabbrowser-tabs'));
await tabs.sendKeys(inpt.Key.CONTROL + inpt.Key.SHIFT + 'k');
})();
Run with node <path-to-script> it achieves the same effect as above: a Firefox window open on google.com, with the console open at the bottom.

Related

WebDriverError: Unknown error, while opening second edge window using Selenium(Javsacript)

I am creating automation tool for Edge Browser using selenium, where I need to open three edge window with three different URLs parallelly.
First Edge browser window launch successfully, but when calling function openEdgeBrowser for second url, it throws Exception: WebDriverError: Unknown error.
const webdriver = require('selenium-webdriver');
const edgedriver = require('edgedriver');
const edge = require('selenium-webdriver/edge');
var openEdgeBrowser = async function(url){
try {
let edgeService = await new edge.ServiceBuilder(edgedriver.path);
let browser = await new webdriver.Builder().forBrowser('MicrosoftEdge').setEdgeService(edgeService).build();
await browser.get(url);
console.log('Browser launched successfully with url: ' + url);
} catch(e) {
console.log.end(`Error in launching edge browser, Exception: ${e}`);
}
};
I expect to run three instances of Edge together.
The problem is that Edge does not support multiple instances:
Hi, This is a known issue.
I just checked the Feedback Hub and I only
see a Microsoft internal posting for this issue. Will you add this to
the Feedback Hub? Open the Feedback Hub app by using the Search Bar
(Win + s) and typing “feedback hub”
The only workaround I am aware of
is to use Selenium grid with multiple Windows Clients. The Clients
can be Hyper-V instances.
Appreciate you reporting this issue and wish
I had a better answer for you. :-/ Steve
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/17754737/
The same has also been noted on twitter.
https://twitter.com/instylevii/status/783480823445987329
I can't find any indication that this bug has been fixed, so I'm going to assume it's still outstanding. It was definitely still outstanding in version 41.16299.15.0 and I can't find anything in the release notes mentioning a fix In version 42.

WebdriverJS Set viewport Size

I want to launch chrome browser with viewport size of some resolution , for example 800x600 , I tried following code
var width = 800;
var height = 600;
driver.manage().window().setSize(width, height);
Above code just resizing window to 800x600 , when I run window.screen.width in developer console it always return 1440
I even tried to add chrome option with --window-size=x,y option
var o = new chrome.Options();
o.addArguments("--window-size=640,480");
driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).setChromeOptions(o).build();
Above code still do the same ,just resizing the window.
Some one please tell me any chrome command line option to set default viewport like we do in chrome developer console (as shown below) , or please tell any option to do directly in selenium webdriverJS.
The code you are providing is working perfectly fine.
However, you are checking the resolution of the screen, not the size of the window! This is what window.screen.width and window.screen.height refer to. To retrieve the size of the window, use window.innerWidth (and innerHeight). The following works for me.
var webdriver = require('selenium-webdriver'),
driver = null;
function logWindowSize() {
driver.executeScript(function() {
return [window.innerWidth, window.innerHeight];
}).then(console.log);
}
// construct driver
driver = new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.build();
driver.get('http://www.google.com');
// resize window
logWindowSize();
driver.manage().window().setSize(640, 480);
logWindowSize();
driver.quit();
This will log the following to my console.
[ 945, 1018 ]
[ 640, 375 ]
Note that the height of the window is different from what was set. This is because of the height of the tab bar and navigation bar. You can set the inner window size by first setting it to an arbitrary value, checking the difference and then setting it to what you want plus that difference. like so.
var webdriver = require('selenium-webdriver'),
driver = null,
sizeWidth = 640,
sizeHeight = 480;
// construct driver
driver = new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.build();
driver.get('http://www.google.com');
// resize window
driver.manage().window().setSize(sizeWidth, sizeHeight);
driver.executeScript(function() {
return [window.innerWidth, window.innerHeight];
}).then(function(actualSize) {
driver.manage().window().setSize(
2 * sizeWidth - actualSize[0],
2 * sizeHeight - actualSize[1]
);
// the following will log the sizes we want
driver.executeScript(function() {
return [window.innerWidth, window.innerHeight];
}).then(console.log);
});
driver.quit();
The problem
It seems that you really want to influence what window.screen.width and window.screen.height return. This is normally not possible, except that these values change when using the device mode (and toolbar) in Chrome. So, let's trigger those, right?
// open inspector and responsive design mode
driver.actions()
.keyDown(Key.CONTROL)
.keyDown(Key.SHIFT)
.sendKeys('im')
.keyUp(Key.SHIFT)
.keyUp(Key.CONTROL)
.perform();
Unfortunately, this won't work in Chrome. To quote that answer:
The Chrome driver uses the Chrome remote debugging protocol to communicate with the browser. This is the same protocol that the developer console uses also. Unfortunately, Chrome is designed so that only one client can be attached using the protocol at a time, so that means either the developer tools, or the driver, but not both simultaneously. — JimEvans
Bummer. It looks like this can be made to work using Firefox, however. Unfortunately, it seems that performing actions is currently not possible using Selenium + geckodriver, at the moment. It is also not possible to open this mode using JavaScript. We can however send keys to an element.
A solution
The following works for me.
var webdriver = require('selenium-webdriver'),
firefox = require('selenium-webdriver/firefox'),
By = webdriver.By,
Key = webdriver.Key,
driver = null;
// construct driver
var profile = new firefox.Profile(),
devicePreset = [{
width: 640,
height: 480,
key: '640x480',
name: 'Mobile Device'
}];
profile.setPreference('devtools.responsiveUI.presets',
JSON.stringify(devicePreset));
var opts = new firefox.Options();
opts.setProfile(profile);
var builder = new webdriver.Builder().forBrowser('firefox');
builder.setFirefoxOptions(opts);
driver = builder.build();
driver.get('http://www.google.com');
// open responsive design mode
driver.findElement(By.css('input[name="q"]'))
.sendKeys(Key.chord(Key.CONTROL, Key.SHIFT, 'm'));
driver.get('https://www.iplocation.net/find-ip-address');
Note that I set a preference for Firefox that indicates the size to use in the responsive design mode. You can change this to whatever screen size you prefer.

Retrieving console log from Firefox 43 with Selenium without Firefox extensions

Is it possible to retrieve the browsers console.log with Selenium and Firefox 43? If so, how?
Here are my settings:
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
LoggingPreferences logs = new LoggingPreferences();
logs.enable(LogType.BROWSER, Level.ALL);
logs.enable(LogType.DRIVER, Level.ALL);
logs.enable(LogType.CLIENT, Level.ALL);
logs.enable(LogType.PERFORMANCE, Level.ALL);
logs.enable(LogType.PROFILER, Level.ALL);
logs.enable(LogType.SERVER, Level.ALL);
capabilities.setCapability(CapabilityType.LOGGING_PREFS, logs);
FirefoxBinary binary = new FirefoxBinary(new File(...));
FirefoxProfile profile = new FirefoxProfile();
WebDriver driver = new FirefoxDriver(binary, profile, capabilities);
//...doing things with the driver ...
driver.manage().logs().get(LogType.BROWSER) // already tried every LogType
The only output i get from this is something like:
1450878255029 addons.xpi DEBUG startup
...
Error in parsing value for 'display'. Declaration dropped.
But not the output which is written in the browsers javascript console log.
I already tried several FF profile settings like:
profile.setPreference("extensions.sdk.console.logLevel", "all");
profile.setPreference("webdriver.log.file",tempfile.getAbsolutePath());
profile.setPreference("webdriver.firefox.logfile", othertempfile.getAbsolutePath());
profile.setPreference("webdriver.log.driver", "ALL");
Nothing helped so far.
In Chrome this is working flawlessly.
Selenium version: 2.48.2
Firefox version: 43.0.2
I had the same issue. I only got all that log noise about css, security, network and what not, but not what was actually logged by the app through console.log. I am using the same version for webdriver and firefox you do. For other browsers this was not a problem.
I ended up extending my client code with custom log recording. Speaking in wire protocol terms:
use execute to put something like the following into the client
window.recordedLogs = [];
console.log = function (message) {
if (typeof message === 'object') {
message = JSON.stringify(message);
}
window.recordedLogs.push(message);
};
use execute to retrieve window.recordedLogs
Warning: the above code is very simplistic, it does not take care of multiple messages passed to the log method, nor does it handle other log methods like info, error, etc.
However it can be a good multi-browser-compliant alternative to the wire protocol log method.

How to automatically accept SSL certs in chrome?

Its been a while I'm trying to figure out a way to automatically accept SSL certs. But unfortunately no luck. So, here is the case, I'm working on selenium tests. And, every time when I run the test on chrome, a small pop-up appears asking to select a certificate.
I tried this in python: How to deal with certificates using Selenium?
I also tried (in javascript):
var options = new chrome.Options();
options.addArguments("--ignore-certificate-errors")
But it doesn't seems to work!
In firefox, there is an option to automatically selects certs. Is there any way in selenium or in chrome settings which automatically selects the certs? Will ENTER/RETURN keys in selenium work?
EDITED: Below is my code. Is this the right way to use?
var launch = function(){
var options = new chrome.Options();
options.addArguments("--test-type");
/* Also tried options.addArguments(“--ignore-certificate-errors")
*/
var driver = new webdriver.Builder()
.usingServer('http://127.0.0.1:4444/wd/hub')
.setChromeOptions(options)
.build();
driver.get(url)
}
P.S Here, I'm using JavaScript.
ACCEPT_SSL_CERTS is one of the browser's desired capability that tells the browser to accept / deny ssl certificates by default.
below is a sample code for accepting SSL certificates in chrome:
DesiredCapabilities cap=DesiredCapabilities.chrome();
// Set ACCEPT_SSL_CERTS variable to true
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
// Set the driver path
System.setProperty("webdriver.chrome.driver","Chrome driver path");
// Open browser with capability
WebDriver driver=new ChromeDriver(cap);
It is major problem with Chrome versions above v.80.
I am currently using version 84.0.4147.105 which won't accept or ignore SSL certificate.
The one thing to do is to downgrade Chrome version below v.80, especially for those of you who are building test cases in local Host applications.
Example using Selenium-grid and Chrome
const { Builder, until, By } = require("selenium-webdriver");
const capabilities = {
browserName: "chrome",
acceptInsecureCerts: true,
};
// alternative require `Capabilities` and do like this:
// const capabilities = Capabilities.chrome().setAcceptInsecureCerts(true);
try {
const driver = await new Builder()
.usingServer("http://localhost:4444/wd/hub")
.withCapabilities(capabilities)
.build();
await driver.get("https://frontend");
// tests
const el = await driver.wait(until.elementLocated(By.id("root")), 2000);
await driver.wait(until.elementIsVisible(el), 2000);
expect(el).not.toBeNull();
// tear down
await driver.quit();
} catch (err) {
throw new Error(err);
}
chrome_options = ChromeOptions()
chrome_options.add_argument('--lang='+language)
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--allow-running-insecure-content')
chrome_options.add_argument('--disable-web-security')
chrome_options.add_experimental_option('useAutomationExtension', False)
if headless :
chrome_options.set_headless()
if remote :
self.driver = webdriver.Remote(command_executor=wd,desired_capabilities=chrome_options.to_capabilities(),options=chrome_options)
else:
self.driver = webdriver.Chrome(desired_capabilities=chrome_options.to_capabilities(),options=chrome_options)

Unable to sendkeys using webdriverjs specifically F11 to maximise the browser

With the below code block it opens a chrome browser fine it just won't full screen the browser using F11. i used to use C# and selenium and that worked fine using this method on chrome and different browsers. It finds the element 'body' but then does not send the key press. Am I doing something wrong here that i should be requiring some other library?
the documentation for webdriverjs is pathetic and there is very few examples, I am seriously considering dumping it for something else possibly python.
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get('https://www.google.co.uk/');
driver.wait(function () {
return driver.getTitle().then(function (title) {
return title === 'Google';
});
}, 1000);
driver.findElement(webdriver.By.xpath('/html/body')).sendKeys("F11");
why are we doing this. we are developing a website that will change depending on size 800x600 + with and without the toolbar depending on how the screen is used different items will be displayed. i can maximise the window using,
driver.manage().window().maximize();
This however still leaves the toolbar present and doesn't act as if the user has pressed the F11 key.
it tooks some time to find it but you should have all the Keys in webdriver.Key
driver.findElement(webdriver.By.xpath('/html/body')).sendKeys(webdriver.Key.F11);
Hope it helps!
A co-worker has just discovered that it works well in C# with:
Driver.Instance.Manage().Window.FullScreen();
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).send_keys(Keys.F11).perform()
I use a similar command to toggle JS via Firefox's NoScript add-on
edit: I just tested, and it works!
This should work for you:
driver.findElement(webdriver.By.xpath('/html/body')).sendKeys(Keys.F11);
You can maximise the window using:
driver.manage().window().maximize();
For me the one emulating correctly the F11 on startup is:
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-fullscreen");
WebDriver driver = new ChromeDriver(options);
Or if the kiosk mode is preferred:
ChromeOptions options = new ChromeOptions();
options.addArguments("--kiosk");
WebDriver driver = new ChromeDriver(options);

Categories

Resources