BrowserStack + Protractor + TravisCi and secure localhost server - configuration - protractor

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.

Related

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

App works locally but not on Heroku (Application Error); Using Nodemon and Webpack

Alright, I've tried to look up my question on StackOverflow but I can't find something that helps me since everything I've tried doesn't have any effect on the result (Application error).
So I'm really stumped because the app works perfectly fine on my localhost, but I can't get it to work on Heroku, it just gives me a Application error so I have no idea what the issue is.
So on my package.JSON file looks like this:
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon --use_strict index.js",
"bundle": "webpack"
},
And I've already tried to change "nodemon" to "node" and gotten rid of --use_strict and ran it on local host and it still works perfectly fine but the Heroku app still gives me a Application Error.
index.js the only thing that I can think of being bad (changed it and it runs here):
// start the server
app.listen(3000, () => {
console.log('Server is running.');
});
webpack.config.js:
const path = require('path');
module.exports = {
// the entry file for the bundle
entry: path.join(__dirname, '/client/src/app.jsx'),
// the bundle file we will get in the result
output: {
path: path.join(__dirname, '/client/dist/js'),
filename: 'app.js',
},
module: {
// apply loaders to files that meet given conditions
loaders: [{
test: /\.jsx?$/,
include: path.join(__dirname, '/client/src'),
loader: 'babel-loader',
query: {
presets: ["react", "es2015"]
}
}],
},
// start Webpack in a watch mode, so Webpack will rebuild the bundle on changes
watch: true
};
It deployed properly after git push heroku master:
https://c1.staticflickr.com/3/2873/33519283263_3d9a711311_z.jpg
I'm pretty much trying to make this app work on Heroku:
https://vladimirponomarev.com/blog/authentication-in-react-apps-creating-components
I think a possible problem might be that you have to run "run bundle" on one shell and "npm start" in the other shell.
Another thing, this app had a lot of things that were npm installed manually in node_modules, which Heroku does not accept if I try to push it on github and will crash, so I'm thinking that might be an issue as well, though I have no idea how to get around that.
This also uses Express and Mongodb, and I added my mongodb info into the index.json file and ran the application, and it worked perfectly fine and after checking the db, the correct info was also inside it, so it's not that either.
You should use process.env.PORT instead of custom port 3000.
Check that you have a mongodb addon purchased, you can get one for free but for limited spacing!
And use the config vars of that database, if you haven't done that already!

Protractor test's within Webstorm has no Browser Connection

While trying to start the default protractor tests, WebStorm or protractor can not launch the default pages inside the Browser.
The Error Message is a simple Exception:
FA Jasmine spec timed out. Resetting the WebDriver Control Flow.
The setup for protractor is as follows:
The protractor.conf.js is as follows
exports.config = {
allScriptsTimeout: 11000,
specs: [
'*.js'
],
capabilities: {
'browserName': 'chrome'
},
baseUrl: 'http://localhost:8000/app/',
framework: 'jasmine2',
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
and the tests are the default webstorm tests.
Configuration looks OK.
Please make sure you have started the local webserver on port 8000 (npm start) prior to running protractor - webserver needs to be serving up the application, so that Protractor can interact with it.
Also, make sure that web driver is installed (npm run update-webdriver)

why won't protractor recognize Angular ?

protractor is giving me errors telling me it can't find angular on the page. what else should I be considering to trouble shoot this ?
protractorConf.js
exports.config = {
seleniumAddress: 'http://0.0.0.0:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
specs: ['spec/javascripts/integration/main_spec.js'],
baseUrl: 'http://127.0.0.1:3000/',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
Failure message, a browser is actually opening, which is an improvement on where i was yesterday, any thoughts on this ?
jd#mbp ~/Dropbox/apps/lookingtolunch (master *)]$ protractor protractorConf.js
Using the selenium server at http://0.0.0.0:4444/wd/hub
F
Failures:
1) E2E: main page should find title element
Message:
Error: Angular could not be found on the page http://127.0.0.1:3000/ : angular never provided resumeBootstrap
Stacktrace:
Error: Angular could not be found on the page http://127.0.0.1:3000/ : angular never provided resumeBootstrap
at assertAngularOnPage (/usr/local/lib/node_modules/protractor/lib/protractor.js:668:13)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
==== async task ====
WebDriver.executeScript()
at Protractor.get (/usr/local/lib/node_modules/protractor/lib/protractor.js:675:15)
at null.<anonymous> (/Users/jd/Dropbox/apps/lookingtolunch/spec/javascripts/integration/main_spec.js:16:13)
at /usr/local/lib/node_modules/protractor/jasminewd/index.js:54:12
at wrapper [as _onTimeout] (timers.js:252:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
==== async task ====
at null.<anonymous> (/usr/local/lib/node_modules/protractor/jasminewd/index.js:53:12)
at null.<anonymous> (/usr/local/lib/node_modules/protractor/node_modules/minijasminenode/lib/async-callback.js:45:37)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
I am also getting the same problem, and since OP has gone silent, maybe I can use this answer space to give a second instance of the problem, and edit it to make it work based on other users feedback.
edit: I've found a solution. See edit at the bottom of the answer
I'm running Windows 8.1 running webdriver-manager start to launch Selenium standalone server, and python -m SimpleHTTPServer to host the site.
example-specs.js
describe("something peaceful", function() {
it("shouldn't be this hard", function() {
browser.get("http://127.0.0.1:8000"); // times out here
expect(true).toEqual(true);
});
});
conf.js
// protractor configuration for end-to-end (e2e) tests
exports.config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
specs: [ 'example-specs.js' ],
}
index.html
<!doctype html>
<html>
<body ng-app >
I can add: {{1+5}}.
<!-- script src="https://ajax.googleapis.com/ajax/libs/angularjs/**1.0.4**/angular.min.js"></script -->
<!-- Updated to 1.2.9 and the problem went away -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
</body>
</html>
edit 1
I was running from WebStorm, but I also tried serving the site using python -m SimpleHTTPServer (and changing the address accordingly), but my results are the same.
edit 2
If I remove baseUrl and call browser.get(...) directly, I can get http://www.angularjs.org work, but not my local site, nor this jsfiddle angular app I found. Maybe it's just not working for automatic bootstrapping?
edit 3
Significantly reduced code to reproduce (removed controller). Moved script to the end of the body as recommended.
edit 4
I was using an old version (1.0.4) of Angular that appeared in this book. Upgrading to 1.2.9 (latest) fixed the problem.
If you need to navigate to a page which does not use Angular then Add this line of code before browser.get() line there:
browser.waitForAngularEnabled(false);
Reference : https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular-on-page-load