how does phantomjs work with protractor? - windows

I am getting my head around protractor and phantomjs. The test looks like this, it works fine with
just chrome:
describe('angularjs homepage', function () {
beforeEach(function () {
browser.driver.manage().window().setSize(1124, 850);
});
it('should greet the named user', function () {
browser.driver.get('https://angularjs.org/');
element(by.model('yourName')).sendKeys('Julie');
var greeting = element(by.binding('yourName'));
expect(greeting.getText()).toEqual('Hello Julie!');
});
});
the protractor.config looks like this :
// An example configuration file.
exports.config = {
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'phantomjs',
'phantomjs.binary.path': 'C:/ptor_testing/node_modules/phantomjs/lib/phantom/phantomjs.exe'
},
// For speed, let's just use the Chrome browser.
//chromeOnly: true,
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['example.spec.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
// onComplete will be called just before the driver quits.
onComplete: null,
// If true, display spec names.
isVerbose: true,
// If true, print colors to the terminal.
showColors: true,
// If true, include stack traces in failures.
includeStackTrace: true,
// Default time to wait in ms before a test fails.
defaultTimeoutInterval: 30000
},
seleniumAddress: 'http://localhost:4444/wd/hub'
};
When I run this i get:
Error: Error while waiting for Protractor to sync with the page: {"message":"Can't find variable: angular","name":"ReferenceError","line":4,"stack":"ReferenceError: Can't find variable: angular\n at :4\n at anonymous (:13)\n at Na (phantomjs://webpage.evaluate():14)\n at phantomjs://webpage.evaluate():15\n at phantomjs://webpage.evaluate():15\n at phantomjs://webpage.evaluate():16\n at phantomjs://webpage.evaluate():16\n at phantomjs://webpage.evaluate():16","stackArray":[{"sourceURL":"","line":4},{"sourceURL":"","line":13,"function":"anonymous"},{"sourceURL":"phantomjs://webpage.evaluate()","line":14,"function":"Na"},{"sourceURL":"phantomjs://webpage.evaluate()","line":15},{"sourceURL":"phantomjs://webpage.evaluate()","line":15},{"sourceURL":"phantomjs://webpage.evaluate()","line":16},{"sourceURL":"phantomjs://webpage.evaluate()","line":16},{"sourceURL":"phantomjs://webpage.evaluate()","line":16}],"sourceId":81819056}
How can I fix this?

Related

Protractor element(by.css('id_name')).getText() causes browser to wait

Version info
Angular CLI: 6.0.8
Node: 8.11.2
OS: win32 x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
#angular-devkit/architect 0.6.3
#angular-devkit/build-angular 0.6.3
#angular-devkit/build-optimizer 0.6.3
#angular-devkit/core 0.6.3
#angular-devkit/schematics 0.6.8
#angular/cdk 6.1.0
#angular/cli 6.0.8
#angular/flex-layout 6.0.0-beta.17
#angular/material 6.1.0
#ngtools/webpack 6.0.3
#schematics/angular 0.6.8
#schematics/update 0.6.8
rxjs 6.2.0
typescript 2.7.2
webpack 4.8.3
Protractor: 5.4.0
jasmine-core: 2.6.2
jasmine-spec-reporter: 4.1.0
Problem
I wanted to make a simple e2e test to check the inner text of an element after the browser has redirected to a page. However, when checking inside of the element, the browser simply sits on the page for 10 seconds and then gives the following error:
1) material App should re-route to login page
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- ScriptTimeoutError: Timed out waiting for asynchronous Angular tasks to finish after 10 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: htt
ps://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
While waiting for element with locator - Locator: By(css selector, #globTitle)
Executed 1 of 1 spec (1 FAILED) in 14 secs.
[20:04:24] I/launcher - 0 instance(s) of WebDriver still running
[20:04:24] I/launcher - chrome #01 failed 1 test(s)
[20:04:24] I/launcher - overall: 1 failed spec(s)
[20:04:24] E/launcher - Process exited with error code 1
An unexpected error occured: undefined
Here is my code:
HTML:
<div class="main-container">
<mat-toolbar [ngStyle]="{'background-color': topBarColor, 'color': 'white'}" class="topbar telative" style = "z-index: 0 !important;">
<button mat-icon-button (click)="snav.toggle()" *ngIf = "showbtn" value="sidebarclosed">
<mat-icon>menu</mat-icon>
</button>
<span id = "globTitle">Programme Admin Dashboard</span>
<span style = "flex: 1 1 auto;"></span>
<button mat-raised-button colour = "warn" *ngIf = "showbtn" (click) = "signOut(); snav.close();" style = "margin-right: 20px;">Sign out</button>
<img src="assets/images/logo.png" alt="No logo available" style = "height: inherit; margin-bottom: 5px;">
</mat-toolbar>
<mat-sidenav-container class="example-sidenav-container" [style.marginTop.px]="mobileQuery.matches ? 0 : 0">
<mat-sidenav style = "text-align: center;" #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]= false [disableClose]="mobileQuery.matches" >
<app-sidebar (click) = "snav.close()"></app-sidebar>
</mat-sidenav>
<mat-sidenav-content class="page-wrapper">
<div class="page-content">
<router-outlet><app-spinner></app-spinner></router-outlet>
</div>
</mat-sidenav-content>
<ng-template #loadingSpinner>
<mat-spinner></mat-spinner>
<p>Fetching permissions...</p>
</ng-template>
</mat-sidenav-container>
</div>
app.po.ts:
import {browser, by, element, protractor} from 'protractor';
export class AppPage {
navigateTo() {
return browser.get('/');
}
getURIChange(url: string) {
const ec = protractor.ExpectedConditions;
browser.wait(ec.urlContains(url), 2000);
}
}
app.e2e-spec.ts:
(Note that when i remove the last line of code, the test manages to run. In fact, even up to element(by.css('#globTitle')) works fine.
But if i change it to element(by.css('#globTitle')).getText(), this is where the browser just waits and i get the error mentioned above.
import { AppPage } from './app.po';
import {browser, element, by} from 'protractor';
describe('material App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should re-route to login page', async () => {
console.log('Waiting for angular');
await browser.waitForAngularEnabled();
console.log('Angular initialized');
console.log('Waiting on navigation to page');
// page.navigateTo();
await browser.get('http://localhost:4201/');
console.log('Navigation completed, should be redirected to the login page');
page.getURIChange('/login');
expect(element(by.css('#globTitle')).getText()).toEqual('Programme Admin Dashboard');
});
});
Also, i'm not sure if this would help, but here are my protractor configuration and karma configurations just in case.
protractor.conf.js:
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 10000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 10000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
karma.conf.js:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
customLaunchers: {
ChromeNoSandbox: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
singleRun: false,
});
};
Try this :
const el1 = await $('#globTitle').getText();
expect(el1).toEqual('Programme Admin Dashboard');
getText() waits for a promise to resolve and hence doesn't work the way it was before.
Hello you are not returning the callback in your step definitions.
So jasmine thinks you are doing or waiting for some actions to happen.But once timeout occured that is 10 seconds it throws an error
it('should re-route to login page', async (done) => {
console.log('Waiting for angular');
await browser.waitForAngularEnabled();
console.log('Angular initialized');
console.log('Waiting on navigation to page'); // page.navigateTo();
await browser.get('http://localhost:4201/');
console.log('Navigation completed, should be redirected to the login page');
page.getURIChange('/login');
Var a = element(by.css('#globTitle');
Var b = a.getText().then((value)=>{console.log('title is'+value);
return value;})
expect(b).toEqual('Programme Admin Dashboard'); done()
});

Expected and Actual Values in Failed Protractor Test Cases

I have recently installed the jasmine-spec-reporter package in order to produce more verbose and helpful logging during execution of test suites.
I want to be able to log expected and actual values for failed test cases and was wondering if I needed to explicitly have a statement in the form of expect(someCondition).toEqual(true); in order for me to see these values.
For example, I have a function like the following:
it('should log in', function(done) {
var customerNameElement;
customerNameElement = element.all(by.xpath('some_xpath')).first();
core.infoMessage(browser, JSON.stringify(params, undefined, 4));
login.login(browser, undefined, undefined, getWaitTime())
.then(function() {
return browser.wait(protractor.ExpectedConditions.and(
function() { return core.isUnobscured(browser, customerNameElement);
}, protractor.ExpectedConditions.elementToBeClickable(customerNameElement)), getWaitTime());
})
.catch(fail)
.then(done);
});
I can still log the failure to the console but not in the form that I'd like. Does jasmine-spec-reporter handle this or do I have to add the statement from above in each test case?
Also, does the fail keyword in the .catch() have any properties I can use to my advantage? It comes from:
// Type definitions for Jasmine 2.5.2 // Project: http://jasmine.github.io/
Thanks
you can try adding the below in protractor_config file:
let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = {
// your config here ...
onPrepare: function () {
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: true
}
}));
}
}
Also, add the print function in the jasmineNodeOptssection
jasmineNodeOpts: {
...
print: function() {}
}

Module name “lib/chai” has not been loaded yet for context: use require([])

it is working well with karma-jasmine.....but not working with karma-mocha...y??
module.exports = function(config){
config.set({
basePath : '../app',
preprocessors: {
'**/*.html':'ng-html2js'
},
ngHtml2JsPreprocessor: {
prependPrefix: '/'
},
files : [
'node_modules/jquery/**/*.js',
'lib/angular/angular.js',
'lib/angular/angular-*.js',
'../test/lib/angular-mocks.js',
'../test/lib/sinon-1.15.0.js',
'../test/lib/chai.js',
'js/**/*.js',
'../test/unit/**/*.js',
'**/*.html'
],
autoWatch : true,
frameworks: ['mocha','requirejs','chai'],
browsers : ['Chrome'],
plugins : [
'karma-chrome-launcher',
'karma-mocha',
'karma-ng-html2js-preprocessor',
'karma-requirejs',
'karma-chai'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});
};
MY SAMPLE CODE:::
'use strict';
describe('calendarHelper', function() {
beforeEach(module('eventsApp'));
it('should return January when given a zero', inject(function(calendarHelper) {
expect(calendarHelper.getMonthName(0)).toBe('January');
}))
});
I came across a similar situation just with Jasmine.
I'd like to introduce my solution.
Try it what is written in the error message. There is a link to a website: http://requirejs.org/docs/errors.html#notloaded
Use this in your spec file:
//If this code is not in a define call,
//DO NOT use require('foo'), but use the async
//callback version:
require(['foo'], function (foo) {
//foo is now loaded.
});
My case written for Jasmine and Sinon in Coffeescript looks like this:
sinon = require(['sinon', 'jasmine-sinon']) (foo)->
Now I can use sinon as an object in my unit test and can also follow the documentation of sinon, as well as jasmin-sinon.

Show specs texts with Jasmine 2, Protractor and Gulp

I have a Gulp configuration file that runs Protractor/Jasmine like this:
.pipe($.protractor.protractor({ configFile: 'protractor.conf.js', args: args || ['--baseUrl', 'http://localhost:' + basePort] }))
But the report shown in the console are just dots, instead of the actual specs tests. How can I make Jasmine be verbose?
This was possible with the isVerbose option in Jasmine 1, but I can't find the equivalent for Jasmine 2.
What we are doing is setting these jasmine settings:
jasmineNodeOpts: {
showColors: true,
isVerbose: true,
includeStackTrace: true,
defaultTimeoutInterval: 100000,
print: function() {}
}
And using jasmine-spec-reporter package that provides a nice and detailed test output:
onPrepare: function () {
var SpecReporter = require('jasmine-spec-reporter');
// jasmine spec reporter
jasmine.getEnv().addReporter(new SpecReporter({
displayStacktrace: 'all',
displayPendingSpec: true,
displaySpecDuration: true
}));
}

Use test.assert in casperjs

For the casperjs, I have:
var casper = require('casper').create({
loadImages:false,
verbose: true,
logLevel: 'debug',
});
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)');
casper.then(function(){
this.echo('step 1 is finished!^.^');
});
I want use casper.test.assert('Step1 is finished');
When I run the code, I cannot use casperjs myjs.js anymore, because the new version need to use casperjs test yourjs.js. But when I use the new one, still give me the error
You can’t override the preconfigured casper instance in this test environment
So, what show I do?
Do exactly what it says. You cannot create a casper instance when you run casper test myjs.js. It will be injected. Just change
var casper = require('casper').create({
loadImages:false,
verbose: true,
logLevel: 'debug',
});
to
casper.options.loadImages = false;
casper.options.verbose = true;
casper.options.logLevel = 'debug';
and use casper inside of test blocks:
casper.test.begin('some test name', function(test) {
casper.start(url);
casper.then(function() {
test.assert(this.getTitle()!=''); // straight forward
})
casper.run(function() {
test.done();
});
});

Resources