setRequestInterception support for Firefox in Puppeteer - firefox

Does setRequestInterception work for Firefox on Puppeteer?
In my tests, whenever launching with Firefox, I do get:
Protocol error (Fetch.enable): Fetch.enable RemoteAgentError#chrome://remote/content/Error.jsm:25:5
on await page.setRequestInterception(true);
I know that currently Firefox is in experimental mode for Puppeteer. So I expect this feature may not be supported.
Is there any other way that I could handle requests (like alter requests, mock responses) when running on Firefox?
This is how I launch the browser (I can see Firefox window, and all other tests pass):
browser = await puppeteer.launch({
product: "firefox",
headless: false,
slowMo: 50,
});

Puppeteer for Firefox does not support setRequestInterception yet.
You can keep a track of passing tests at https://puppeteer.github.io/ispuppeteerfirefoxready/
Here is how we launch firefox:
During installation, choose Puppeteer version ^3.0.0
PUPPETEER_PRODUCT=firefox npm install
Options:
puppeteerOptions: {
args: args,
//ignoreDefaultArgs: ['--enable-automation'],
headless: false,
//slowMo: 17,
//executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
executablePath: './node_modules/puppeteer/.local-firefox/mac-79.0a1/Firefox Nightly.app/Contents/MacOS/firefox'
},

Related

Unable to run chrome with Testcafe on macOS

I have been trying without success to run tests on chrome using Testcafe in MacOS. I have generated all the certificates required but when launching chrome with testcafe it reports ERR_SSL_VERSION_OR_CIPHER_MISMATCH. Below are the arguments I am passing -
yarn run testcafe --hostname localhost --ssl 'pfx = testingdomain.pfx;rejectunasuthorized=true;--ssl key = testingdomain.key;cert=testingdomain.crt' "chrome --use-fake-ui-for-media-stream --allow-insecure-localhost --allow-running-insecure-content" e2e/testmac.js --live
When I remove loading PFX cert and run below, I am able to get to the webpage, but cant access mic and camera. My command to maximzie browser window also does not work
yarn run testcafe --hostname localhost "chrome --use-fake-ui-for-media-stream --allow-insecure-localhost --allow-running-insecure-content --live" e2e/testmac.js --ssl 'key=testingdomain.key;cert=testingdomain.crt' --live
My simple test -
import { Selector, ClientFunction } from 'testcafe';
fixture`Audio Configuration Combination`.page`http://XXX.XXX.XXXXXX/sandbox/index.html`;
test('Launch SDK,', async (browser) => {
await browser.getCurrentWindow().maximizeWindow().wait(100000);
});
I have problems only on mac. Same setup is working fine on windows. I need to access mic and camera and so passing in "--use-fake-ui-for-media-stream". But I dont see a camera preview. Passing in "--use-fake-device-for-media-stream" loads up fake devices which is something I dont need.
Any help is greatly appreciated.
According to this comment on GitHub, it should be sufficient to use either of the two approaches to mock user media, not necessarily both. If you specify testcafe --hostname localhost, you shouldn't need to specify --ssl at all.
I ran the following test from the GitHub discussion mentioned above on macOS:
mock-media-test.js
fixture `WebRTC`
.page`https://webrtc.github.io/samples/src/content/getusermedia/canvas/`;
test(`test`, async t => t.wait(30000));
I used the following command:
testcafe "chrome --use-fake-ui-for-media-stream" mock-media-test.js --hostname localhost
The test ran as expected, and the page displayed the stream from my camera. The --use-fake-device-for-media-stream flag worked for me as well.

How to run Jasmine tests in headless mode?

I have to run Jasmine tests in headless mode and I could find PhantomJS Laucher but the project has been suspended PhantomJS
Is there any other way to run Jasmine tests in headless mode? If so, please point me to helpful docs, posts etc.
I found a nice post. You can use HeadlessChrome for the headless mode.
ng test --browsers ChromeHeadless
It is also possible to change the karma and protractor configuration to create a custom laucher or to change the capabilities for the chrome browser.
Protractor configuration you can make necessary changes
Run in it on Chrome Headless using below config
capabilities = {
browserName: 'chrome',
chromeOptions: {
args: ['--headless', '--no-sandbox']
}
};
Run in on Firefox as headless using below config
capabilities: {
browserName: 'firefox',
firefoxOptions: {
args: ['--headless']
}
}

Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError) with Selenium ChromeDriver in Cucumber Ruby

We have Cucumber Ruby automation framework where we run few tests on Chrome headless browser in a Docker on Jenkins. A few days ago we started receiving an error "This version of ChromeDriver only supports Chrome version 75" this time we were using ChromeDriver 2.46 and with google-chrome-unstable browser using the following command:
#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-unstable
RUN apt-get install unzip
# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 2.46
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH
I have now updated chromedriver version to 75.0.3770.8 and browser to google-chrome-beta=75.0.3770.27-1
#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-beta=75.0.3770.27-1
RUN apt-get install unzip
# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
RUN echo $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH
And now I can see the error as:
unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError)
Is it possible to disable W3C mode or download an older version of Chrome browser and driver that doesn't use it? I think the possibility to disable W3C check would be great.
All you have to do is just to disable the W3C when initializing the webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option('w3c', False)
create_webdriver('Chrome', options=options)
Environment:
Chrome 75
ChromeDriver 75
This error message...
unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError)
...implies that the ChromeDriver was unable to call non W3C standard command while in W3C mode while initiating/spawning a new WebBrowser i.e. Chrome Browser session.
Here the main issue is, when ChromeDriver's client requests a W3C-compliant session but the response from ChromeDriver does not conform to the W3C spec, and causes errors in language APIs.
Analysis
As per the discussion in ChromeDriver response in W3C mode is not standard compliant John Chen (Owner - WebDriver for Google Chrome) mentioned that, Simon Stewart (Creator - WebDriver) had updated that:
The new session response for a w3c session should look like:
{
"value": {
"sessionId": "some-uuid",
"capabilities": {
"browserName": "chrome",
...
}
}
}
But when starting a new session with the w3c option set to true in the chromeOptions as follows:
Selenium/Python:
from selenium import webdriver
opt = webdriver.ChromeOptions()
opt.add_experimental_option('w3c', True)
driver = webdriver.Chrome(chrome_options=opt)
Selenium/Java:
{
"sessionId": "af4656c27fb94485b7872e1fc616923a",
"status": "ok",
"value": {
"browserName": "chrome",
...
}
}
The returned response looks like:
{
"sessionId": "af4656c27fb94485b7872e1fc616923a",
"status": "ok",
"value": {
"browserName": "chrome",
...
}
}
Which is neither a correctly formed response for the JSON Wire Protocol (where "status" would be an integer), nor a correctly formed W3C response and without a correctly formed response, the w3c compatible cannot be used.
Relevant part of the spec: https://w3c.github.io/webdriver/webdriver-spec.html#new-session
Relevant tests from spec: https://github.com/w3c/web-platform-tests/pull/5187
ChromeDriver version: 2.31.488774 (7e15618d1bf16df8bf0ecf2914ed1964a387ba0b)
Chrome version: 60.0.3112.90 (Official Build) (64-bit)
This revision and this commit addressed this issue.
This usecase
As you are using ChromeDriver v75.x and Chrome v75.x and you are still seeing the same error, you need to pass the ExperimentalOption w3c as true exclusively as follows:
capabilities = { "chromeOptions" => {'w3c' => true} }
Update
Till ChromeDriver v74.x, Chrome and ChromDriver combo was running in w3c mode by default but there was bug with in the chromedriver/server/http_handler.cc. As per the details in goog:chromeOptions.w3c=false doesn't work for POST request with empty body:
Method HttpHandler::HandleCommand checks the value of the kW3CDefault constant instead of session goog:chromeOptions.w3c value. As a result, JSON Wire protocol support was broken, where POST requests with an empty body are allowed.
JSON Wire protocol will be in demand until displayed endpoint is resumed in the w3c mode. It should be noted that W3C WebDriver specification doesn't forbid the use of 'displayed' endpoint and this feature is actively used in some APIs.
As Is Element Displayed command is not part of W3C spec, but is still used by some APIs, and its functionality can be difficult to replicate in those APIs. This Change List [revision and commit] re-enables this command in W3C mode to ease transition to W3C mode.
#John have already confirmed us to expect an update to ChromeDriver v75.0 tomorrow with the fix.
Here's the solution
As promised by John Chen [Owner - WebDriver for Google Chrome], ChromeDriver versions 75.0.3770.90 and 76.0.3809.25 have been released, and are now available at the ChromeDriver Downloads site. These versions include the following bug fixes over the previous releases of ChromeDriver 75 and 76:
Fixed a bug that incorrectly rejected POST requests with empty body in OSS mode
Added new endpoints for retrieving Chrome log
In addition, version 76.0.3809.25 also includes the following change:
Added endpoint for Is Displayed command in W3C mode
Snapshot
If you are getting this error using rails + rspec + capybara + selenium, the way to pass the option to disable W3C is as follows:
Capybara.register_driver :chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: {'w3c' => false}
)
Capybara::Selenium::Driver.new(app, :browser => :chrome, desired_capabilities: capabilities)
end
Just add w3c: false in the end like in this example:
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: ["window-size=#{DEFAULT_X_RES},#{DEFAULT_Y_RES}"], w3c: false })
For my PHP friends who search the depths of the internet...
The newest version of PHPUnit_Extensions_Selenium2TestCase
Which is at the moment a composer constraint of
"phpunit/phpunit-selenium": ">=7",
"phpunit/phpunit": ">=6"
Can use the following options. Note my struggle::
'w3c' => false
This must be a boolean and not a string.
class NavigationTest extends PHPUnit_Extensions_Selenium2TestCase
{
public function setUp()
{
static $count;
$count or $count = 1 and print PHP_EOL . 'java -jar ' . dirname(__DIR__) . '/selenium-server-standalone-3.141.59.jar' . PHP_EOL;
self::shareSession(true);
$this->setDesiredCapabilities([
"chromeOptions" => [
'w3c' => false
]
]);
$this->setHost('localhost');
$this->setPort(4444);
$this->setBrowser('chrome');
$this->setBrowserUrl('http://localhost:9919/');
$this->prepareSession()->currentWindow()->maximize();
}
}
Not sure what framework you're using but i have the same error after updating my browser & chromedriver to latest one v75.0.3770.90. My suggestion is that looking for the session init section in your scripts and add the option to disable w3c.
E.g mine before upgrading:
chrome_options = Selenium::WebDriver::Chrome::Options.new
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)
after upgrading
chrome_options = Selenium::WebDriver::Chrome::Options.new
chrome_options.add_option('w3c',false)
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)
In my case it was different version of selenium that not supported w3c. Decrease chromedriver to version 74.0.3729.6 make all work work. It could also be fixed by updateing selenium version to latest that support W3C.
Please start reading documentation instead of "just disabling" something that is there for a reason.
For example, executing scripts:
/session/{session id}/execute/sync
/session/{session id}/execute/async

Browsersync - How to choose which installation of browser to run?

I've just installed Firefox Dev Edition, and I don't know how to tell browsersync to start with it when I launch it.
I know there is the browser option in which I can specify "firefox", but how can I differenciate one FF installation from one other ?
The issue would be the same if I had various regular FF installed (eg a 3.5, a 48.x and a 50.x).
I can always open manually the right FF and load the page after browsersync started, but I would like it to do it manually (and not to be opened in my regular non-dev FF).
In fact, it was quite easy: if you put the absolute path to an executable file in the browser option, it takes it smoothly.
So options should be something like :
{ port: 9000,
server: {
baseDir: [...
],
routes: {
'/bower_components': 'bower_components',
'/node_modules': 'node_modules',
'/temp': 'temp'
}
},
logLevel: 'info',
notify: true,
browser: 'C:\\Program Files (x86)\\Firefox Developer Edition\\firefox.exe',
reloadDelay: 0 //1000
}

Setting user agent on firefox with protractor and using seleniumAddress does not work

I want to set a specific user agent using protractor and Firefox. If I use directConnect on protractor.conf.js, it works:
//selenium-webdriver is installed via npm
var firefox = require('selenium-webdriver/firefox');
var firefoxProfile = new firefox.Profile();
firefoxProfile.setPreference("general.useragent.override", 'monitoring1152936086');
exports.config = {
directConnect: true,
capabilities: {
'browserName': 'firefox',
'firefox_profile': firefoxProfile
},
...
}
However, if I use seleniumAddress instead of directConnect it does not work. Test does work but the user agent is not used. I need to use a selenium server. For example:
var firefox = require('selenium-webdriver/firefox');
var firefoxProfile = new firefox.Profile();
firefoxProfile.setPreference("general.useragent.override", 'monitoring1152936086');
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
'browserName': 'firefox',
'firefox_profile': firefoxProfile
},
...
}
As a side note, I cannot use chrome since I am trying to use Firefox as a workaround to the not so stable combination of protractor and selenium-docker with chrome (https://github.com/SeleniumHQ/docker-selenium/issues/87).
Any ideas? Thanks!
In the direct connect case Protractor creates the browser itself, so it's able to have total configuration over the browser. In the remote case Protractor has less control because it's connecting to the selenium server started up by webdriver-manager. The correct time to pass a firefox profile would be when webdriver-manager starts, but Protractor does not currently provide this feature.

Resources