Bypass docker to run selenium scripts locally - selenium

I have selenium scripts to run on docker container selenium grid that were written before I join this project. due to the docker I don't have access to view the browser while running the scripts. And when scripts fail its very hard to debug. Can someone help me how to modify the below conf.js file to run my scripts locally for debugging.
Conf.js
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
const log = require('loglevel');
const util = require('#raven/common-protractor-test-utils');
const { ExpectedConditions } = require('protractor');
require('dotenv').config({ path: '.local.env' })
var testOutputDir = './test_output/';
let peregrineUrl = util.functionalTestBaseUrl(
'https://ea-webapp-int-raven.ocp-nonprod/'
);
let domainName = util.domainName;
exports.config = {
directConnect: true, // Set to true for local testing, or provide a link to a running selenium grid.
specs: ['e2e/**/mailbox-test.js', 'e2e/**/email-dumps-test.js'],
capabilities: {
browserName: 'chrome',
acceptInsecureCerts: true,
'goog:chromeOptions': {
w3c: false,
args: [
'--no-sandbox',
// '--headless',
'--disable-gpu',
'--window-size=1200,1200',
'--allow-insecure-localhost',
'--allow-running-insecure-content',
'--ignore_ssl',
'--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
],
},
},
allScriptsTimeout: 600000,
baseUrl: peregrineUrl,
framework: 'jasmine',
jasmineNodeOpts: {
isVerbose: true,
showColors: true,
includeStackTrace: true,
defaultTimeoutInterval: 600000,
stackTrace: true
},
onPrepare: async () => {
/* Set Log Level */
log.setLevel('INFO');
log.info('Base URL: ' + peregrineUrl);
log.info('Domain Name: ' + domainName);
browser.ignoreSynchronization = true;
const ec = protractor.ExpectedConditions;
/* Set up the test directory. */
util.mkdirs(testOutputDir);
console.time('Peregrine Load Time');
await browser.get(peregrineUrl);
browser.driver.sleep(3000);
await username_area.sendKeys('rv-peregrine-test-user');
await password_area.sendKeys(process.env.SELENIUM_SERVICE_PASSWORD);
await agree_button.click();
await login_button.click();
},
};
When I try to change directConnect: ture and disable --headless to run locally I am able to see the chrome browser launched but the application opened. This is the trace from my console
[21:28:19] I/launcher - Running 1 instances of WebDriver
[21:28:19] I/direct - Using ChromeDriver directly...
DevTools listening on ws://127.0.0.1:51650/devtools/browser/bf44c6c7-72a6-49e5-ab80-b13139ce9005
[15808:15796:0115/212822.298:ERROR:url_util.cc(414)] Invalid pattern javascript://
[15808:4128:0115/212826.609:ERROR:chrome_browser_main_extra_parts_metrics.cc(227)] START: ReportBluetoothAvailability(). If you don't see the END: message, this is crbug.com/1216328.
[15808:4128:0115/212826.610:ERROR:chrome_browser_main_extra_parts_metrics.cc(230)] END: ReportBluetoothAvailability()
[15808:4128:0115/212826.611:ERROR:chrome_browser_main_extra_parts_metrics.cc(235)] START: GetDefaultBrowser(). If you don't see the END: message, this is crbug.com/1216328.
[15808:15796:0115/212826.611:ERROR:device_event_log_impl.cc(214)] [21:28:26.611] USB: usb_device_handle_win.cc:1050 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
[15808:15796:0115/212826.613:ERROR:device_event_log_impl.cc(214)] [21:28:26.613] USB: usb_device_handle_win.cc:1050 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
[15808:4128:0115/212826.672:ERROR:chrome_browser_main_extra_parts_metrics.cc(239)] END: GetDefaultBrowser()
[15808:15796:0115/212826.687:ERROR:device_event_log_impl.cc(214)] [21:28:26.688] Bluetooth: bluetooth_adapter_winrt.cc:1206 Getting Radio failed. Chrome will be unable to change the power state by itself.
[15808:15796:0115/212826.730:ERROR:device_event_log_impl.cc(214)] [21:28:26.730] Bluetooth: bluetooth_adapter_winrt.cc:1284 OnPoweredRadioAdded(), Number of Powered Radios: 1
[15808:15796:0115/212826.732:ERROR:device_event_log_impl.cc(214)] [21:28:26.732] Bluetooth: bluetooth_adapter_winrt.cc:1299 OnPoweredRadiosEnumerated(), Number of Powered Radios: 1
Thanks in advance

Related

Why does a simple automation test with Appium fail?

I'm developing an application with React Native and I'm experiencing difficulties in test automation with the Appium framework.
I have never used the tool and my first goal is to check if the following element exists on the main screen. PS: the element exists.
<TouchableOpacity
testID="test-login"
accessibilityLabel="test-login"
>
<Text>test login</Text>
</TouchableOpacity>
In the project, I created the test folder with the sample.test.js file
const webdriverio = require('webdriverio');
const androidOptions = {
capabilities: {
browserName: 'Chrome',
allowInsecure: {},
denyInsecure: {},
},
desiredCapabilities: {
browserName: 'Chrome',
path: '/wd/hub',
port: 4723,
platformName: 'Android',
app:
'/Users/xxx/android/app/build/outputs/apk/debug/app-debug.apk',
deviceName: 'xxx', // adb devices
automationName: 'Appium',
appPackage: 'XXX',
launchActivity: 'XXX.MainApplication',
chromeOptions: {w3c: false},
ensureWebviewsHavePages: true,
platformVersion: '8.0.0',
},
};
describe('things', () => {
let client;
before(async () => {
client = await webdriverio.remote(androidOptions);
});
it('test', async () => {
//await client.elementByAccessibilityId('test-login');
//client.elementsByAccessibilityId('test-login');
await client.findElementsByAccessibilityId('test-login');
//let elementsOne = await client.elementsByAccessibilityId('test-login');
//let elementsTwo = await client.elements('id', 'test-login');
//await client.elementByAccessibilityId('test-login').isClickable;
});
after(async () => {
return await client.deleteSession();
});
});
and run it with node ./node_modules/.bin/mocha.
The output is
things
INFO webdriverio: Initiate new session using the devtools protocol
INFO devtools: Launch Google Chrome with flags: --disable-extensions --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-sync --metrics-recording-only --disable-default-apps --mute-audio --no-first-run --disable-hang-monitor --disable-prompt-on-repost --disable-client-side-phishing-detection --password-store=basic --use-mock-keychain --disable-component-extensions-with-background-pages --disable-breakpad --disable-dev-shm-usage --disable-ipc-flooding-protection --disable-renderer-backgrounding --enable-features=NetworkService,NetworkServiceInProcess --disable-features=site-per-process,TranslateUI,BlinkGenPropertyTrees --window-position=0,0 --window-size=1200,900
INFO devtools: Connect Puppeteer with browser on port 51345
1) test
✓ should create and destroy Android browser session
INFO devtools: COMMAND deleteSession()
INFO devtools: RESULT null
0 passing (1s)
1 failing
1) things
test:
TypeError: client.findElementsByAccessibilityId is not a function
at Context.it (test/sample.test.js:97:18)
at process.topLevelDomainCallback (domain.js:126:23)
The android phone with the application in debug mode is connected to the computer.
I have tried snippets about it but without success.
Could you help me with the first step?
Thank you all.
The error says "TypeError: client.findElementsByAccessibilityId is not a function"
Which means the object returned from webdriverio.remote, doesn't have a findElementsByAccessibilityId function.
You should add something like this:
console.log(Object.getOwnPropertyNames(client));
or
console.log(Object.getOwnPropertyNames(client).filter(x => typeof client[x] == 'function'));
before the client.findElementsByAccessibilityId call to see what it actually contains.

How can I access localStorage of Cordova App via WebdriverIO and Appium?

I'm currently trying to write some automated tests for our cordova app written in Angular.
My current setup is the following:
Versions:
appium: 1.7.2
wdio-appium-service: 0.2.3
webdriverio: 4.11.0
wdio.conf.js
exports.config = {
port: 4723,
logLevel: 'error',
capabilities: [{
platformName: 'Android',
platformVersion: '8.1',
deviceName: 'any',
app: '../cordova_app/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
autoWebview: true,
autoGrantPermissions: true
}],
// specs: ['./tests/spec/**/*.js'],
specs: ['./tests/spec/login.js'],
services: ['appium'],
reporters: ['spec'],
framework: 'jasmine',
jasmineNodeOpts: {
defaultTimeoutInterval: 90000
}
}
tests/spec/login.js
describe('Language and market choosing process', () => {
beforeEach(() => {
browser.timeouts('implicit', 2000);
});
afterEach(() => {
browser.reload();
});
it('should go through login process', () => {
const selectCountryBtn = $('.fsr-login__market-chooser');
selectCountryBtn.click();
// everything works so far
browser.localStorage('POST', {key: 'test', value: 'test123'});
// Failed: unknown error: call function result missing 'value'
});
});
When I run this test on my Android 8.1 emulator, the test crashes as soon as it reaches the localstorage part with the error:
Failed: unknown error: call function result missing "value"
Error: An unknown server-side error occurred while processing the command.
at localStorage("POST", [object Object]) - index.js:316:3
The localStorage API of WebdriverIO is described here
What am I doing wrong?
I agree that localStorage manipulation is a tricky endeavour to tackle, especially cross-browser, cross-platform, etc. When dealing with application cookies, or local storage, I default to using plain JS commands to achieve my goal.
As such, I would recommend you try the browser.execute() command to manipulate the browser's local storage:
browser.execute("localStorage.setItem('socialMediaRuinsTheWorld', true)");
or
browser.execute((keyName, keyValue) => {
localStorage.setItem(keyName, keyValue);
}, "testing", "theLocalStorage");
Outcome:
Appium API doesn't offer function localStorage.
I think this is your problem. Also if you use 3.4 version, check Appium section, not only Protocol. Native apps don't have same localStorage as browser and you can't access to it easily.

Custom args for each instance of Chrome when running parallel tests with Protractor

Is it possible to pass custom args for each instance of Chrome when running parallel tests in Protractor? I need to know the Remote debugging port for each instance so I can connect with the Dev Tools protocol.
As I see it there's two options. Set the port to a specific unique value for each instance, or let it be set automatically and fetch it somehow when preparing the tests. Would it be possible with any of these options?
exports.config = {
framework: 'jasmine',
chromeDriver: chromeDriverPath,
multiCapabilities: [{
browserName: 'chrome',
chromeOptions: {
args: process.env.HEADLESS && puppeteer ? ['--headless', `--remote-debugging-port=${DEV_TOOLS_PORT}`] : [`--remote-debugging-port=${DEV_TOOLS_PORT}`],
binary: puppeteer.executablePath()
},
shardTestFiles: true,
maxInstances: 1
}]
}
If I got the problem right, what you could do is to pass parameters as env variables to protractor on start. So your config would look like this:
exports.config = {
framework: 'jasmine',
chromeDriver: chromeDriverPath,
multiCapabilities: [{
'browserName': 'chrome',
'chromeOptions': {
args: [`--remote-debugging-port=${process.env.PORT_ONE}`]
}
}, {
'browserName': 'chrome',
'chromeOptions': {
args: [`--remote-debugging-port=${process.env.PORT_TWO}`]
}
}]
}
And then start your protractor process with env variables like so:
PORT_ONE=90 PORT_TWO=80 protractor protractor.conf.js
One of the two options are solved. But I would still like to know if there's a possibility to use custom args for each instance.
// Get Remote debugging port for chrome
let chromeRemoteDebuggingPort;
browser.getCapabilities().then((capabilities) => {
const chromeOptions = capabilities.get('goog:chromeOptions');
if( chromeOptions && chromeOptions.debuggerAddress) {
chromeRemoteDebuggingPort = chromeOptions.debuggerAddress.split(':')[1];
}
});

Selenium standalone only works with chrome

I'm using my protractor tests run with a selenium standalone server.
Now i want to support all browsers.
I created a folder with the standalone (3.0.1) and a subfolder driver with IEDriver, geckodriver, chromedriver.
I added the path to the driver folder to the system PATH.
The standalone is running with no args (i do not know what to add).
My Config is:
var TIMEOUT = 20000;
exports.config = {
seleniumAddress: 'http://localhost:4448/wd/hub',
baseUrl: 'https://intmachine.project.com/',
/*
list the Suites to run locally here
*/
specs: [
'./UseCases/protractorTestcaseNightly.js',
],
capabilities: [
{
'browserName': 'firefox',
'firefox_binary':'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe'
// shardTestFiles: false,
// maxInstances: 1,
// maxSessions: -1,
// restartBrowserBetweenTests: true,
},
],
getPageTimeout: TIMEOUT,
allScriptsTimeout: TIMEOUT,
jasmineNodeOpts: {
defaultTimeoutInterval: TIMEOUT,
isVerbose: true,
includeStackTrace: true
},
framework: "jasmine2",
//rootElement: 'html',
onPrepare: function () {
browser.driver.manage().window().maximize();
browser.driver.manage().deleteAllCookies();
}
};
Update:
i changed "Capa..." to capabilities and now get:
[launcher] Running 1 instances of WebDriver
[launcher] Error: TypeError: Target browser must be a string, but is <undefined>; did you forget to call forBrowser()?
at TypeError (native)
at Builder.build (C:\dev\dcps-angular\node_modules\selenium-webdriver\builder.js:417:13)
at DriverProvider.getNewDriver (C:\dev\dcps-angular\node_modules\protractor\built\driverProviders\driverProvider.js:42:27)
at Runner.createBrowser (C:\dev\dcps-angular\node_modules\protractor\built\runner.js:203:37)
at C:\dev\dcps-angular\node_modules\protractor\built\runner.js:293:21
at _fulfilled (C:\dev\dcps-angular\node_modules\q\q.js:834:54)
at self.promiseDispatch.done (C:\dev\dcps-angular\node_modules\q\q.js:863:30)
at Promise.promise.promiseDispatch (C:\dev\dcps-angular\node_modules\q\q.js:796:13)
at C:\dev\dcps-angular\node_modules\q\q.js:556:49
at runSingle (C:\dev\dcps-angular\node_modules\q\q.js:137:13)
[launcher] Process exited with error code 100

How to setup Selenium grid remotely in protractor

I have my conf.js file which runs fine locally. But now as per my requirement I need to run it in a bamboo task. Since my code is going to run on server there is a remote selenium webdriver that i need to add to the conf.js.
Can you please help me out how it is done? My conf.js looks like this :
exports.config = {
params: {
url: "URL",
testroadname:"Testing123",
sleeptime:1000
},
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['mapfeedback.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
You have to remove directConnect = true and just give the seleniumAddress in your config or setup an environment.js file- you can simply add your remote selenium's address and fire up your protractor tests, following will be your environment.js-
// Common configuration files with defaults plus overrides from environment vars
var webServerDefaultPort = 8081;
module.exports = {
// The address of a running selenium server.You can add your remote address here
seleniumAddress:
(process.env.SELENIUM_URL || 'http://localhost:4444/wd/hub'),
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName':
(process.env.TEST_BROWSER_NAME || 'chrome'),
'version':
(process.env.TEST_BROWSER_VERSION || 'ANY')
},
// Default http port to host the web server
webServerDefaultPort: webServerDefaultPort,
// Protractor interactive tests
interactiveTestPort: 6969,
// A base URL for your application under test.
baseUrl:
'http://' + (process.env.HTTP_HOST || 'localhost') +
':' + (process.env.HTTP_PORT || webServerDefaultPort)
};
your config file will look like -
var env = require('./environment.js');
exports.config = {
params: {
url: "URL",
testroadname:"Testing123",
sleeptime:1000
},
seleniumAddress: env.seleniumAddress,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['mapfeedback.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
To setup selenium-grid remotely for Protractor :-
start hub with command :-
java -jar selenium-server-standalone-3.3.1.jar -role hub -port 4444
Now start your remote node with command where you want execute remote test cases :-
java -jar selenium-server-standalone-3.3.1.jar -role webdriver -hub http://HubDomain-IP:4444/grid/register -port 5556 -browser browserName=internet explorer,maxInstances=1,platform=WINDOWS,applicationName=remoteNode -Dwebdriver.ie.driver=path to IEDriverServer.exe
Once your selenium-grid setup is done and node get connected with Hub, then take config file with configuratiion set as this conf.js file:-
exports.config = {
//The address of your running selenium Hub server.
seleniumAddress: 'http://HubDomain-IP:4444/wd/hub',
//Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'internet explorer',
// add node-name as applicationName where you have started node and wanted to remotely execute test cases
'applicationName': 'remoteNode'
},
//Specify the name of the specs files.
specs: ['grid_spec.js'],
//Options to be passed to Jasmine-node.
jasmineNodeOpts: {
onComplete: null,
isVerbose: false,
showColors: true,
includeStackTrace: true
}
};
With above mentioned configuration and setup commands you could run selenium-grid setup for Protractor.Thanks !