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.
Related
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
So I am trying to do something very simple yet so hard to understand for me the reason why its not working.
I am using browserstack combined with protractor and it is as simple as adding this to the config:
let SpecReporter = require('mochawesome').SpecReporter;
exports.config = {
baseUrl: 'http://testing.net/',
"browserstackUser": "test",
"browserstackKey": "1234",
multiCapabilities: [
{
os_version: "9.0",
device: "Samsung Galaxy S10 Plus",
real_mobile: false,
browserName: "Android",
project: "Selenium-Test",
build: "Build 1337",
name: "Mobile - Happy Flow"
}
],
mochaOpts: {
reporter: "mochawesome",
timeout: 60000,
},
suites: {
all: 'pages/*.js',
},
framework: 'mocha',
};
and whenever I run the code it starts by:
describe('FIRST TEST', function () {
var EC = protractor.ExpectedConditions;
browser.waitForAngularEnabled(false);
browser.manage().window().maximize();
brwoser.get('http://testing.net/');
}
and it seems to be stuck through here. I was watching the live demo of what is happening and it seems like it doesn't want to open the URL even thought I do have the link which is odd. and I am not sure if I am doing anything wrong for mobile version but yeah.
The problem is I can't open any URL for the phones but works well on desktop
Can you remove browser.manage().window().maximize(); for the mobile code
You can review a sample provided by BrowserStack in the link: https://github.com/browserstack/protractor-browserstack and execute the tests on similar lines
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.
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];
}
});
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