ReferenceError: driver is not defined in Protractor - protractor

I'm a beginner. Can any one guide me?
Tests.js
describe("Test the calculator",()=>{
it("Addition functionality",function test(){
driver.browser.get("https://juliemr.github.io/protractor-demo/");
browser.manage().window().maximize();
//browser.manage().timeouts().implicitlyWait(3000)
})
})
Config.js
const driver= require("protractor")
exports.config= {
browserName: 'chrome',
framework: "mocha",
directconnect: true,
specs: ['./tests.js'],
mochaOpts: {
timeout: 0
}
}
At run time it display a message as "driver is not defined"
Chrome version: 83.0.4103.61 (Official Build) (64-bit)
Visual Studio code: 1.45.1

I see what's going on...
first of all, don't call protractor a driver. Don't confuse others and most importantly yourself. Protractor is protractor, period.
second, when you do const driver= require("protractor") your driver variable is available in conf.js, but when you call it from the spec, it's not there, because it's a local variable, not global. As simple as that, this is why you get this error
Third, you don't need to define protractor because it is a global variable, and is available anywhere in your project anyways. The same with browser, element, $, $$ they all are available globally in your project.
Fourth, lets assume for whatever GOOD reason you still want to define something that will be globally available just do global.driver = require('protractor') as described here https://stackoverflow.com/a/31208642/9150146, and then you can call by typing the variable name driver

Related

Protractor - log type 'performance' not found error

webdriver-manager 12.1.5
protractor Version 5.4.2
Chrome version 75.0.3770.100
browser.manage().logs().get('performance');
This used to work fine before upgrading my webdriver-manager and protractor version.
(node:27715) UnhandledPromiseRejectionWarning: WebDriverError: invalid argument: log type 'performance' not found
(Session info: chrome=75.0.3770.100)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'
System info:, os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.14.4', java.version: '1.8.0_191'
Driver info: driver.version: unknown
at Object.checkLegacyResponse (node_modules/selenium-webdriver/lib/error.js:546:15)
If I comment the browser.manage().logs().get('performance'); and other performance related code, then the test runs fine.
webdriver-manager logs show:
Starting ChromeDriver 75.0.3770.90 on port 12268
I came across a potential solution on this github issue thead. Apparently recently chromedriver has started to more strictly adhere to W3C standards and this has affected how webdriver activates logs.
We can get around this issue by setting the w3c: false flag in chromeoptions like so.
capabilities: {
browserName: 'chrome',
loggingPrefs: {
browser: 'ALL',
driver: 'ALL',
performance: 'ALL',
},
'goog:chromeOptions': {
perfLoggingPrefs: {
enableNetwork: true,
},
w3c: false,
},
},
New version might not support performance log type. You can always use getAvailableLogTypes function to check supported log types. I tried following code
var supportedLogTypes = await browser.manage().logs().getAvailableLogTypes();
received ouptput :
It means you can only use either of two supported log types.
I tried out the same thing with chrome 75.* and protractor 5.4.2 version. Following are my findings.
loggingPrefs object is one of the recognized capabilities like chromeOptions. This object allow us to decide preferences on logging part. Refer link for more details about capabilities.
In protractor context we have to pass loggingPrefs object to capabilities to enable it.
Once we pass it then we can use browser.manage().logs().get('performance'); to get all performance logs.
If you want to change perfLoggingPrefs then it is part of chromeOptions object and it has to be updated there. If we want to use default then no need to mention.
chrome use more strictly rule for w3c, when I test chrome driver 96, set w3c to false, I can get network log, but find_element failed and return dict value which is not WebElement

Protractor test fails on CI

Currently I am trying a setup an end to end protractor tests to a a bitbucket pipelines with set up an headless chrome and i am currently getting some error message:
Failed: This driver instance does not have a valid session ID (did you call WebDriver.quit()?) and may no longer be used.
Any clue for this? how ever running tests locally is working fine; Can i set a constant session id?
Thanks
Check out your configuration file for this object
capabilities: {
"browserName": "chrome",
"chromeOptions": {
"args": ["incognito", "--window-size=1920,1080", "disable-extensions", "--no-sandbox", "start-maximized", "--test-type=browser"],
"prefs": {
"download": {
"prompt_for_download": false,
"directory_upgrade": true,
"default_directory": path.join(process.cwd(), "__test__reports/downloads")
}
}
}
},
When you find it, make sure you included "--no-sandbox" argument into args property.
What this guy does is it allows your tests to be ran from a remote container. In the meantime, if you include the argument when you run your tests on your machine, it has side effects like described here Chrome Instances don't close after running Test Case in Protractor

How can I know the base url used in a running test in protractor?

I'm trying to do navigation test in protractor and don't see any consitency with the baseUrl in the config and the url used in the test.
protractor.conf.js
exports.config = {
baseUrl: 'http://localhost:4200/'
}
navbar.e2e-spec.ts
import { NavbarPage } from './navbar.po';
import * as protractor from './../protractor.conf.js';
describe('navbar', () => {
let navbar: NavbarPage;
const baseUrl = protractor.config.baseUrl;
beforeEach(() => {
navbar = new NavbarPage();
browser.get('/');
});
it(`should see showcase nav item, be able to (click) it,
and expect to be navigated to showcase page`, () => {
const anchorShowcase = navbar.anchorShowcase;
expect(anchorShowcase.isDisplayed()).toBe(true);
anchorShowcase.click();
browser.waitForAngular();
expect(browser.getCurrentUrl()).toBe(baseUrl + '/showcase');
});
});
Although when I run the e2e test it uses a different port:
** NG Live Development Server is listening on localhost:49154, open your browser on http://localhost:49154/ **
Why is the test url set to port 49154. This apparently seems to be the default if you start a new angular-cli project: https://github.com/angular/angular-cli
How can I get control over the baseUrl / Or is http://localhost:49154/ safe to use for all my angular cli projects?
By default when you do ng e2e the command take --serve value as true. It means it will build and serve at that in a particular URL. Not the baseUrl you passed in protractor.conf.js
that is why, you are getting a random URL served when testing you app like http://localhost:49154/
Now as you don't want build during test and want to test existing build (URL) like http://localhost:4200/ you need to pass --no-serve in your command line and it will pick baseUrl from the protractor.conf.js
you can also pass baseUrl in the command line like below. note that this not baseUrl but --base-href=
ng e2e --no-serve --base-href=https://someurl.com:8080
When running Angular CLI's ng e2e command, it states in the wiki that the default port will be random, as seen here:
https://github.com/angular/angular-cli/wiki/e2e
Under the serve submenu.
The e2e command can take in all the same arguments as serve so to keep the port the same just pass in --port my-port-number to the ng e2e command.
As far as that port being safe to use, I wouldn't use it, it is just a random port after all. I would stick to the default unless you have a use-case for changing it. The port is mainly relevant for the dev server, not so much for where ever the production code runs.
Aniruddha Das's solution doesn't work anymore as this option isn't there from Angular CLI 6.x version, you can try following -
ng e2e --dev-server-target=
please see following reference

BrowserStack + Protractor + TravisCi and secure localhost server - configuration

Trying to have an e2e test to test my server and it's UI on TraviCI. I'm however not able to come up with the necessary configuration in order to run all the components and access seleniumServer on BrowserStack.
I am able to get my session started, but when launching a browser to https://localhost:3000/login I see that the browser shows a page not found. If I manually run the ./BrowserStackLocal tool and use browserstack to access my localhost, I can do so no problem.
Here are my files:
./travis.yaml
....
addons:
browserstack:
username: "<my username>"
access_key:
secure: "<secure key goes here>"
config.js
var browserstack = require('browserstack-local');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'specs/*.js'
],
'seleniumAddress': 'http://hub.browserstack.com/wd/hub',
'capabilities': {
'browserstack.user': '<my username>', //<<--- I also had a version without these properties for browserstack, and that didn't work either
'browserstack.key': '<my key>',
'browserName': 'chrome',
'acceptSslCerts': true,
'browserstack.debug': true,
'chromeOptions': {
'excludeSwitches': ["disable-popup-blocking"]
}
},
baseUrl: 'https://localhost:3000/',
rootElement: 'div[ng-app]',
framework: 'jasmine',
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
},
// Code to start browserstack local before start of test
beforeLaunch: function(){
console.log("Connecting local");
return new Promise(function(resolve, reject){
exports.bs_local = new browserstack.Local();
exports.bs_local.start({'key': exports.config.capabilities['browserstack.key'] }, function(error) {
if (error) return reject(error);
console.log('Connected. Now testing...');
resolve();
});
});
},
// Code to stop browserstack local after end of test
afterLaunch: function(){
return new Promise(function(resolve, reject){
exports.bs_local.stop(resolve);
});
}
};
Since you are testing your local/private environment on BrowserStack Automate you have to follow these steps:
1) Create the Local Testing connection via the BrowserStackLocal Binary.
2) Add the capability 'browserstack.local' : true in your config file.
I do not see the capability in the config.js file. Add the capability and things should work.
Your script looks similar to the one here.
I ran into this same problem myself recently. First, Ashwin is right that you need to add 'browserstack.local' : true to your protractor config file. Next you need to add "browserstack-local": "^1.3.0" to package.json under devDependencies. This is required for the Browserstack Local binary to be installed on your build server.
package.json:
...
"devDependencies": {
"browserstack-local": "^1.3.0"
}
Beyond that, it is not a problem with the config/setup. Rather, it is how you kick off the tests that affects the port your app is served on.
The reason it works when you run with the local binary is because your app is started on http://localhost:3000.
But when you build and run the app via Travis (by running ng e2e or similar), it actually starts your app on a different port (refer to this post for more on the angular ports). You can confirm this by looking at the console log, it should start with something like this:
> ng e2e
** NG Live Development Server is listening on localhost:49152, open your browser on http://localhost:49152 **
In the example above, it started on port 49152. So now if you have localhost:3000 hardcoded somewhere in your test spec, it won't find anything there. To fix this, in your test spec file, instead of browser.get('http://localhost:3000/login'), try browser.get(browser.baseUrl + '/login').
I realize this answer is probably too late for you, but hopefully it will be helpful to others.

Protractor - Change Browser Capabilities at RunTime

Is there a way to change the browser capabilities within beforeEach of the protractor suite. I need to set the Capabilities.name attribute before each spec execution.
To create separate instances of the desired capabilities, such as capabilities.name, you will want to try the multiCapabilities option available via Protractor. An example would look similar to what is below and reside in the conf.js file. This allows you to submit a unique name for each test session.
onPrepare: function(){
var caps = browser.getCapabilities()
},
multiCapabilities: [{
browserName: 'firefox',
version: '32',
platform: 'OS X 10.10',
name: "firefox-tests",
shardTestFiles: true,
maxInstances: 25
}, {
browserName: 'chrome',
version: '41',
platform: 'Windows 7',
name: "chrome-tests",
shardTestFiles: true,
maxInstances: 25
}],
A complete example of this can be seen here:
https://github.com/saucelabs-sample-test-frameworks/JS-CucumberJS-Protractor3.0/blob/master/conf.js
Here are the sauceLabs capabilities:
https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options
When you don't specify a Capabilities.name it looks like sauceLabs reports each test formatted as browserName:specFilename by default.
You can't change the capabilities in beforeEach() (Jasmine hook) or onPrepare() (Protractor conf.js) because the browser instance has already been created and webdriver session has been started with the capabilities already sent to the Selenium server.
Desired capabilities are set in the conf.js under Capabilities or Multicapabilities. You could set them at runtime by getting a variable before exporting in conf.js.
One common way to do this is to set the capability using an environment variable, for example:
Capabilities: {
browserName: process.env.SELENIUM_BROWSER
}
You can set variables to be used in capabilities in beforeLaunch() but this executes one time only, before any specs are read.
There is an excellent summary of the Protractor / Jasmine hooks here:
http://timothymartin.azurewebsites.net/protractor-before-and-afters/
I have not yet identified a way (without modifying Protractor source) to change capabilities dynamically on a per-spec or per-suite basis.