Automating webrtc Screenshare - protractor

I am trying to automate screen share workflow in a webRTC application.
I need to bypass the screenshare prompt. I am using --use-fake-ui-for-media-stream, use-fake-device-for-media-stream and --auto-select-desktop-capture-source flags in my config file.
Doesn't seem work.
Here is my config file :
exports.makeDefaultCapabilities = function(that) {
return {
browserName: 'chrome',
chromeOptions: {
// disable Password manager popup
prefs: {
credentials_enable_service: false,
download: {
prompt_for_download: false,
directory_upgrade: true,
default_directory: '~/Downloads'
}
},
args: [
'disable-infobars=true',
'--use-fake-device-for-media-stream',
'--use-fake-ui-for-media-stream',
'--auto-select-desktop-capture-source = "Entire screen"'
]
},
loggingPrefs: {
driver: 'WARNING',
server: 'WARNING',
browser: 'INFO'
},
I tried flipping between using fake-device and fake-ui flags and they do not get along if i understand correctly.
I do not understand what is missing here. Appreciate your inputs.
Thanks

https://bugs.chromium.org/p/chromium/issues/detail?id=459532#c22 explains why those flags don't play well together and how to workaround it by creating a custom profile that has already accepted getUserMedia permissions which makes the use-fake-ui-for-media-stream flag unnecessary.
See here for some code.

Related

Set Internet Explorer options for protractor (--headless)

I would like to set headless option in my protractor configuration for internet explorer, but I cannot find anyting related to this. They only say how to do it in Chrome and Firefox: Adding chrome and Firefox specific options.
This is what I have so far:
multiCapabilities: [
{
'browserName': 'chrome',
chromeOptiaons: {
args: ["--headless"]
},
},
{
'browserName': 'firefox',
'moz:firefoxOptions': {
args: ["--headless"]
}
},
{
'browserName': 'internet explorer',
internetExplorerOptions: { <---------------------------
args: ["--headless"] <---------------------------
}
}
],
internetExplorerOptions is not working
So how do I add the 'Options / args' option to IE?
IE does not have support for a headless mode. But you can try to use triflejs.
I did not try this solution by myself but seems like it's the only option since IE is basically obsolete browser and it does not receive any updates.
First of all, you need IEDriverServer.
I will try to make this as simple as possible. The proper way to get and install this is, by using protractor’s built-in functionality.
Install Webdriver-manager and gulp, globally.
npm installwebdriver-manager gulp -g
Browse to node_modules/protractor/bin and run
npm webdriver-manager --standalone update
npm webdriver-manager --ie update
Then, you will need to manually start the webdriver server
For this, you will need to run
npm webdriver-manager --ie start
As simple as that.
After that, the 2nd step is to get the config file right.
The spicy and “different” stuff is: Capabilities, direct connect, and
LocalSeleniumStandaloneOpts
Necessary and Important examples for config file, in order to run the spec test suite:
capabilities: {
'browserName': 'internet explorer',
'ignoreProtectedModeSettings': true,
'platform': 'ANY',
'version': '11',
args: ['--silent', '--no-sandbox', '--test-type=browser', '--lang=US', '--start-maximized'], //,'--headless', '--disable-gpu'
prefs: {
'download': {
'prompt_for_download': false,
'directory_upgrade': true,
'extensions_to_open': '',
'default_directory': process.cwd() + '/downloads/'
},
}
},
localSeleniumStandaloneOpts: {
jvmArgs: [
'-Dwebdriver.ie.driver=node_modules/protractor/node_modules/webdriver-manager/selenium/IEDriverServer3.14.0.exe'
]
},
directConnect: false,
framework: 'jasmine',
seleniumArgs: ['-
Dwebdriver.ie.driver=node_modules/protractor/node_modules/webdriver-
manager/selenium/IEDriverServer3.14.0.exe'],
seleniumAddress: 'http://localhost:4444/wd/hub'

Protractor W3C capability

I am using Protractor with Selenoid. I need to use the dockerized Windows images so that I can test Internet Explorer and Edge from Linux boxes.
I was able to make it work from curl by running:
curl -X POST http://127.0.0.1:4444/wd/hub/session -d '{"capabilities":{"browserName":"MicrosoftEdge","count":1,"alwaysMatch":{"browserName":"MicrosoftEdge","selenoid:options":{"enableVNC":true,"enableVideo":false,"enableLog":true,"logName":"edge-18.0.log"}}}}'
My protractor config looks like:
multiCapabilities: [
{
browserName: "MicrosoftEdge",
"alwaysMatch": {
browserName: "MicrosoftEdge",
"selenoid:options": {
enableVNC: true,
enableVideo: false,
enableLog: true,
logName: "edge-18.0.log"
}
}
}
]
But protractor send it over the selenoid server like this:
{
"desiredCapabilities": {
"browserName": "MicrosoftEdge",
"count": 1,
"alwaysMatch": {
"browserName": "MicrosoftEdge",
"selenoid:options": {
"enableVNC": true,
"enableVideo": false,
"enableLog": true,
"logName": "edge-18.0.log"
}
}
}
}
The issue is that desiredCapabilities should just be 'capabilities`. I have been looking everywhere trying to find out where is that created so that I can created some sort of flag to be able to switch it.
Any ideas?
Using Protractor 6.0 solve my issue, but broke all my tests.
I was able to keep using 5.4.1 by patching the selenium-webdriver package. Looking at the way Protractor 6 did it, I did it to Protractor 5.4.1:
I edited the file located at node_modules/selenium-webdriver/lib/webdriver.js and added the following:
// Capability names that are defined in the W3C spec.
const W3C_CAPABILITY_NAMES = new Set([
'acceptInsecureCerts',
'browserName',
'browserVersion',
'platformName',
'pageLoadStrategy',
'proxy',
'setWindowRect',
'timeouts',
'unhandledPromptBehavior',
]);
Then in the same file I modify the static createSession(executor, capabilities, opt_flow, opt_onQuit) method to add the following:
let W3CCaps = new Capabilities(capabilities);
for (let k of W3CCaps.keys()) {
// Any key containing a colon is a vendor-prefixed capability.
if (!(W3C_CAPABILITY_NAMES.has(k) || k.indexOf(':') >= 0)) {
W3CCaps.delete(k);
}
}
cmd.setParameter('capabilities', W3CCaps);
After all those changes the request getting to Selenoid is like this:
{
"desiredCapabilities": {
"browserName": "MicrosoftEdge",
"version": "18.0",
"enableVNC": true,
"enableVideo": false,
"count": 1
},
"capabilities": {
"browserName": "MicrosoftEdge"
}
}
And my Protractor 5 config looks like this:
multiCapabilities: [{
browserName: 'MicrosoftEdge',
version: '18.0',
enableVNC: true,
enableVideo: false
}]
Note:
So that I don't have to worry about refresh installs or updates I use the package patch-package (https://github.com/ds300/patch-package) to create a patch that is applied when any of those events happen. Here is a great video explaining how to use that package https://www.youtube.com/watch?v=zBPcVGr6XPk

Protractor to dynamically choose browser based on input

I am new to protractor and I want to be able to run my chrome browser painted or headless.
So I set up something like this
let chrome = {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
};
let chromeHeadless = {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
};
browserDefault = browser.params.browserToUse
exports.config = {
params: {
'browserToUse': "get from user'
},
capabilities: browserDefault,
}
and i ran this code as
protractor config.js --params.browserToUse='chromeHeadless'
But this does not work. Protractor fails saying it does not understand "browser.params.browserInput". Whats the right way to make protractor dynamically choose chrome or chromeheadless based on the input
The global variable browser is only init when code run into onPrepare(). You used browser outside onPrepare() function, browser have not been inited, it is undefined, so you met the error.
Another point you need to get it's when the variable browser inited, a browser window has been opened, means protractor has know which capabilities to launch the browser. Therefore you can't use browser.params.xxx to specify which capabilities, you need to tell protractor the capabilities before it init the browser variable.
let capabilitiesMap = {
'chrome-headful' : {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
},
'chrome-headless': {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
}
};
let browserToUse = 'chrome-headful'; // set default value
// extract the browserToUse value from cli
process.argv.slice(3).forEach(function(arg) {
var name = arg.split('=')[0];
var value = arg.split('=')[1];
var name = name.replace('--', '');
if (name === 'browserToUse') {
if (Object.prototype.hasOwnProperty.call(capabilitiesMap, value) ) {
browserToUse = value;
}
}
});
let config = {
seleniumAddress: '',
specs: [],
onPrepare: function() {}
};
config.capabilities = capabilitiesMap[browserToUse];
exports.config = config;
CLI example: protractor conf.js --browserToUse=chrome-headless
I also came across this issue and soleved it using the getMultiCapabilities() function in your conf.js
const _ = require('lodash');
let capabilities = {
chrome: {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
},
chromeHeadless : {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
}
}
getMultiCapabilities() {
const browsers = this.params.browserToUse.split(',');//if you pass more than one browser e.g chrome,chromeHeadless
const cap = _(capabilities).pick(browsers).values().value(); //this uses the lodash npm module
return cap;
},
In a testing context working with just Chrome, I did the following. In capabilities:
chromeOptions: {
args: []
}
beforeLaunch: function() {
//at this point browser is not yet defined, so process command line directly
if (process.argv[process.argv.length-1].search('headless=true')>-1){
config.capabilities.chromeOptions.args.push("--headless");
config.capabilities.chromeOptions.args.push("--disable-gpu");
config.capabilities.chromeOptions.args.push("--window-size=1600,1000");
}
}
That way by the time the browser was launched, it had the right configuration. Where I have "headless=true", you might want "Chrome-headless."
And then on the command line I call it like you do with --params.headless=falseso that should I want to find it in the script itself later (after the browser has launched), it is readily available.
Note I had just one command line parameter and control of the command line, so it felt okay to assume this parameter was the last.

Protractor - invalid SSL certificate

We have an application and testing this locally shows an invalid SSL certificate warning. Normally I would just add an exception and get on with it. However is there anyway for protractor to ignore this?
I've seen some capabilities in selenium where SSL can be ignored but can't seem to find any in protractor.
This works for me, (in conf file):
capabilities: {
browserName : 'firefox',
marionette : true,
acceptInsecureCerts : true
}
Hope that helps.
capabilities: {
browserName: 'chrome',
chromeOptions: {
// for ci test
args: ['--headless', 'no-sandbox', "--disable-browser-side-navigation",
"--allow-insecure-localhost"
/// for https sites: ignore ssl on https://localhost...
/// further args please see https://peter.sh/experiments/chromium-command-line-switches/
]
}
}
maybe you want to take some screenshots to test where the error occurs
import fs from 'fs';
function writeScreenShot(data, filename) {
const stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
export function takeScreenshot(browser, path){
browser.takeScreenshot().then((png) => {
writeScreenShot(png, path);
});
}
But for the long run, I would suggest migrating to cypress (https://www.cypress.io/), because it have many other features out of the box: video, screenshot, etc. And believe me, it is worth it ;)
try
webdriver-manager update --ignore_ssl
or configure protractor.conf.js for firefox
var makeFirefoxProfile = function(preferenceMap) {
var profile = new FirefoxProfile();
for (var key in preferenceMap) {
profile.setPreference(key, preferenceMap[key]);
}
return q.resolve({
browserName: 'firefox',
marionette: true,
firefox_profile: profile
});
};
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
framework: 'jasmine2',
getMultiCapabilities: function() {
return q.all([
makeFirefoxProfile(
{
'browser.acceptSslCerts': true
}
)
]);
},
}

Meteor User Accounts - Facebook login not showing but Google is

I am trying to integrate the Meteor UserAccounts Bootstrap package following this guide.
I have set the ServiceConfiguration properly for both the services but only Google shows up. I also tried adding Twitter but even that does not work. Does anyone have any idea what I'm missing?
Packages -
meteor-platform
accounts-password
iron:router
aldeed:collection2
useraccounts:bootstrap
nemo64:bootstrap
less
accounts-google
service-configuration
fortawesome:fontawesome
accounts-facebook
accounts-twitter
Accounts configuration on the server -
// /server/lib/config/accoutns.js
Meteor.startup(function() {
// Add Facebook configuration entry
ServiceConfiguration.configurations.update(
{ service: "facebook" },
{ $set: {
appId: "xxxxxxxxxxxxxxxxxxxx",
secret: "xxxxxxxxxxxxxxxxxxx"
}
},
{ upsert: true }
);
// Add Google configuration entry
ServiceConfiguration.configurations.update(
{ service: "google" },
{ $set: {
clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
client_email: "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
secret: "XXXXXXXXXXXXXXXXXXXXXXXX"
}
},
{ upsert: true }
);
ServiceConfiguration.configurations.update(
{ service: "twitter" },
{ $set: {
consumerKey: "XXXXXXXXXXXX",
secret: "XXXXXXXX"
}
},
{ upsert: true }
);
});
But this is all that comes up -
EDIT1: I just noticed something very interesting. I cloned this exact project on my friend's macbook and everything is coming up perfectly as expected. (I was using a Linux mint 17 earlier). I think this is some kind of a bug but not sure what is culprit here.
You may be using ublock or adblock on your browser. Simply disable it and it'll work.
Its a bit weird but it looks like while Meteor is unminified it blocks anything with facebook or twitter in its url such as the facebook/twitter packages' js code.