How can I use Protractor with google.com? - testing

google.com isn't an Angular app, but Protractor should still be able to test it, right? I've been trying to do a simple test of a search, but keep running to errors.
the spec:
browser.ignoreSynchronization = true;
describe('Google Demo', function() {
it('Should Search', function() {
browser.get('http://google.com/');
browser.wait(element(By.id('q')).isPresent);
element(By.id('q')).sendKeys('please work');
});
});
the error is:
Failures:
1) Google Demo Should Search
Message: TypeError: Cannot read property 'count' of undefined
What am I doing wrong? I'd appreciate any help!

Since it's a non-Angular app, you need to use browser.driver instead of just browser. GitHub Link for non-angular app
browser.ignoreSynchronization = true;
describe('Google Demo', function() {
it('Should Search', function() {
browser.driver.get('http://google.com/');
browser.driver.findElement(by.name('q')).sendKeys('please work');
});
});
This is working on my system!

this also works for non angular apps
browser.waitForAngularEnabled(false);
describe('Google search', function() {
it('should search a text as GURU99', function() {
browser.waitForAngularEnabled(false);
browser.get('https://www.google.com');
element(by.name("q")).sendKeys('test')
browser.sleep(5000);
});
});

Related

Cucumber + Protractor - timed out error while executing the steps

I am using cucumber and protractor to write behavioural driven tests.My scenarios and all the steps will pass but at the end it will show timed out error. The homepage will get loaded for the first step and later it will not perform any steps described in the steps definition file. Once the page is loaded it should click on the tabs. I have mentioned these steps in step definition file.But these steps are not executed and it will show all the steps passed in the console. I followed this link for reference https://semaphoreci.com/community/tutorials/getting-started-with-protractor-and-cucumber
This is the error message
Please find the sample code below.
//sample.feature
Feature: The Dashboard has 2 tabs, Statistics and Results
Scenario: I want to have 2 tabs with Displayed text "Statistics" and "Results" on the homepage
Given I go to Dashboard homepage
And I click on the "#/results"
Then the Results page is displayed
And I click on the "#/Statistics" tab
Then the Statistics page is displayed
//menu.steps.js
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
module.exports = function() {
this.Given(/^I go to Dashboard homepage$/, function() {
browser.get('http://localhost:8100/#/');
browser.waitForAngular();
});
this.Then(/^I click on the "([^"]*)"$/,function(arg1){
element(by.css('[href="#/results"]')).click();
});
this.Then(/^the results page is displayed$/, () => {
browser.get('http://localhost:8100/#/results');
});
this.When(/^I click on the "([^"]*)" tab$/, function(arg1) {
element(by.css('[href="#/statistics"]')).click();
});
this.Then(/^the statistics page is displayed$/, () =>{
browser.get('http://localhost:8100/#/statistics');
});
//cucumber.conf.js
exports.config = {
framework: 'custom', // set to "custom" instead of cucumber.
frameworkPath: require.resolve('protractor-cucumber-framework'),
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['test/e2e/cucumber/*.feature'],
capabilities: {
'browserName': 'firefox',
},
baseUrl: 'http://localhost:8100/#/',
// cucumber command line options
cucumberOpts: {
require: ['test/e2e/cucumber/*.steps.js'], // require step definition files before executing features
tags: [], // <string[]> (expression) only execute the features or scenarios with tags matching the expression
strict: true, // <boolean> fail if there are any undefined or pending steps
format: ["pretty"], // <string[]> (type[:path]) specify the output format, optionally supply PATH to redirect formatter output (repeatable)
dryRun: false, // <boolean> invoke formatters without executing steps
compiler: [] // <string[]> ("extension:module") require files with the given EXTENSION after requiring MODULE (repeatable)
},
onPrepare: function () {
browser.manage().window().maximize(); // maximize the browser before executing the feature files
},
resultJsonOutputFile: './test/e2e/results.json'
}
If you are using CucumberJS, you can choose to use callbacks or promises. In your code, you didn't use one of them. Below, you will find an example of your steps how you can use promises, of callbacks.
Be aware of the fact that you if you implement one of the 2 solutions, your tests could still fail, but that has more to do with the test implementation instead of the solution for callbacks / promises
// With promises
module.exports = function() {
this.Given(/^I go to Dashboard homepage$/, function() {
browser.get('http://localhost:8100/#/');
return browser.waitForAngular();
});
this.Then(/^I click on the "([^"]*)"$/, function(arg1) {
return element(by.css('[href="#/results"]')).click();
});
this.Then(/^the results page is displayed$/, () => {
return browser.get('http://localhost:8100/#/results');
});
this.When(/^I click on the "([^"]*)" tab$/, function(arg1) {
return element(by.css('[href="#/statistics"]')).click();
});
this.Then(/^the statistics page is displayed$/, () => {
return browser.get('http://localhost:8100/#/statistics');
});
}
// With callbacks
module.exports = function() {
this.Given(/^I go to Dashboard homepage$/, function(done) {
browser.get('http://localhost:8100/#/');
browser.waitForAngular().then(done);
});
this.Then(/^I click on the "([^"]*)"$/, function(arg1, done) {
element(by.css('[href="#/results"]')).click().then(done);
});
this.Then(/^the results page is displayed$/, (done) => {
browser.get('http://localhost:8100/#/results').then(done);
});
this.When(/^I click on the "([^"]*)" tab$/, function(arg1, done) {
element(by.css('[href="#/statistics"]')).click().then(done);
});
this.Then(/^the statistics page is displayed$/, (done) => {
browser.get('http://localhost:8100/#/statistics').then(done);
});
}

Protractor "restartBrowserBetweenTests: true" restart browser, but don't run test after this

I need to restart browser after each "it" (test), for this reason I write "restartBrowserBetweenTests: true" in protractor.config file. Now after first "it" (test) finished, browser closed and opened again (open website that I write in "beforeEach", but next "it" (test) is not run.
What I do wrong? I will be happy for any advice.
I use "protractor": "2.5.1".
Thanks!
Added:
beforeEach(function () {
browserUtil.navigateTo(browserUtil.url.main);
loginPage.loginAsSample();
});
afterEach(function(){
browserUtil.deleteCookies();
});
it("'Delete' button is inactive if there are no projects in the list", function() {
projectPage.clickOnProjectButton();
expect(projectPage.isProjectPageFormVisibility(true)).toBe(true);
expect(projectPage.isDeleteBtnDisable()).toBe(true);
});
it("Create new project with template 'A'", function() {
projectPage.clickOnNewProjectBtn();
projectPage.clickOnAProject();
projectPage.clickOnOkBtnProject();
expect(projectPage.isOpenedProjectVisibility(true)).toBe(true);
});
I've never utilized restartBrowserBetweenTests: true, but this works for me:
in protractor.conf, remove restartBrowserBetweenTests: true
in test.spec.js, modify beforeEach and afterEach
beforeEach(function () {
browser.get(browserUtil.url.main);
});
afterEach(function () {
browser.manage().deleteAllCookies();
});
Being that you're utilizing a page object structure for your tests, you could/would want to encapsulate browser.get(browser.browserUtil.url.main); into you're page object.
Where ProjectPage is defined, I'd add :
this.refreshPage = function () {
browser.get(browserUtil.url.main);
};
If you go with this approach, you'd change the call on beforeEach to :
beforeEach(function () {
projectPage.refresh();
});

casperjs can't click on reddit.com

my casperjs click is working fine in most web site, but when i try to click something on reddit, it wont click.
casper.start();
casper.then(function (){
this.open("http://reddit.com");
});
casper.then(function(){
this.sendKeys("[name='user']", 'someusername');
this.sendKeys("[name='passwd']", 'somepassword');
this.click("[id='rem-login-main']");
this.click(x('//*[#id="login_login-main"]/div[3]/button'))
});
casper.run();
the sendkeys function is working well, but both click function is not workin, please help!
Find the below code and its working
casper.test.begin("Opening Reddit page", 1, function suite(test) {
var x = require('casper').selectXPath;//required if we detect an element using xpath
casper.start();
casper.viewport(1024, 768).then(function () {
this.open("http://reddit.com");
this.wait(5000)
});
casper.then(function () {
this.sendKeys("[name='user']", 'username');
this.sendKeys("[name='passwd']", 'password');
this.click("[id='rem-login-main']");
this.click(x(".//*[#id='login_login-main']/div[3]/button"));
});
casper.wait(5000)
casper.then(function () {
this.test.assertExists(x(".//*[#id='header-img']"), "Confirmed that page has successfully loaded");
});
casper.run(function () {
test.done();
});
});

chai spy passes to.be.spy assertion, but throws error on .called() "is not a spy or a call to a spy"

I am attempting to use chai spies in my unit tests. I am using karma, mocha, chai and sinon.
I was originally trying to use chai spies to verify a callback in my angular app was called when provided. But to solve the error I have boiled my test case down to what I think is a pretty simple one.
I have the below unit test
describe('spy tests:', function() {
it('should be spy', function() {
var spy = chai.spy();
expect(spy).to.be.spy;
});
it('should have been called', function() {
var spy = chai.spy();
spy();
expect(spy).to.have.been.called();
});
}
The first "should be spy" test passes, which as far as I can reason means that a spy is in fact being created. However the second test fails with the below error:
TypeError: { [Function]
toString: { [Function: toString] bind: { [Function: bind] bind: [Circular] } },
reset: { [Function] bind: { [Function: bind] bind: [Circular] } },
__spy: { calls: [ [] ], called: true, name: undefined },
bind: { [Function: bind] bind: [Circular] } } is not a spy or a call to a spy!
This is particularly frustrating as I just verified it is a spy in the previous "should be spy" assertion.
Below are my frameworks, as I am including them in my karma.conf.js:
frameworks: ['chai-as-promised', 'chai-things', 'chai-spies', 'sinon-chai', 'chai', 'mocha']
To make matters more frustrating the below assertion does pass:
expect(spy.__spy.called).to.be.true;
I am happy to provide any other info needed. Thanks!
I'm not a chai spies expert, but I was having similar issues getting chai spy to work.
I just tested the function, and there appears to be a missing ")" bracket at the end; Maybe it's a copy and paste error?
describe('spy tests:', function() {
it('should be spy', function() {
var spy = chai.spy();
expect(spy).to.be.spy;
});
it('should have been called', function() {
var spy = chai.spy();
spy();
expect(spy).to.have.been.called();
});
});
If that's not the issue, then I was able to create a successful chai spy test by overwriting my function variable with spy.
function functionA() {
}
function thatCallsFunctionA() {
functionA();
}
describe('Function thatCallsFunctionA', function() {
it('Should call functionA', function() {
var functionA = spy(functionA);
thatCallsFunctionA();
expect(functionA).to.have.been.called();
});
})

Functional testing with grunt-webdriver, mocha and chai-as-promised

I'm trying to build a functional testing system to verify our web site is behaving correctly for our users. I have cobbled together a bunch of Node.js modules and helpers in an attempt to get a framework that provides simple, concise tests without a heap of nested function callbacks and I believe promises can provide that, so my package.json file looks like this:
"dependencies": {
"chai-as-promised": "^4.3.0",
"grunt": "^0.4.5",
"grunt-webdriver": "^0.4.8"
}
My Gruntfile.js looks like this:
module.exports = function(grunt) {
grunt.initConfig({
webdriver: { // for use with webdriver.io
options: {
desiredCapabilities: {
browserName: 'phantomjs' // No Xvfb required
}
},
chrome: {
tests: ['chrome/*.js'],
options: {
desiredCapabilities: {
browserName: 'chrome'
}
}
},
},
});
grunt.loadNpmTasks('grunt-webdriver');
grunt.registerTask('default', ['webdriver']);
};
And finally my test case in chrome/login.js looks like this:
'use strict';
var chai = require('chai'),
chaiAsPromised = require('chai-as-promised'),
assert;
chaiAsPromised.transferPromiseness = browser.transferPromiseness;
chai.use(chaiAsPromised);
assert = chai.assert;
describe('login test', function () {
it('verifies user can log in', function(done) {
browser
.url('https://localhost/')
.setValue('#userauth_username','foo')
.setValue('#userauth_password',"password")
.submitForm('#form_users_login')
.then(function(){
browser.getText('#auth-user-id', function(err, value){
console.log(value);
});
assert.becomes(browser.getText('#auth-user-id'), 'foo');
})//.call(done);
});
});
When I run grunt webdriver:chrome on the command line, I see it start up Chrome and log into the website. The 'auth-user-id' span is correctly displaying the user's id after logging in but for some reason browser.getText() is not returning it and the test is therefore failing. I have tried adding a .pause(100) after the .submitForm() to give me time to interact with the page in Chrome so I know it is a problem in the test case.
What am I doing wrong?
This seems to be the best and most succinct way of doing what I want. I'm not sure I need chai-as-promised yet but maybe I'll move the login function to an included file and use chai-as-promised to assert that the promised login has occurred before entering the tests.
'use strict';
var chai = require('chai'),
chaiAsPromised = require('chai-as-promised'),
assert,
expect;
chaiAsPromised.transferPromiseness = browser.transferPromiseness;
chai.use(chaiAsPromised);
assert = chai.assert;
expect = chai.expect;
describe('login test', function () {
it('verifies user can log in', function(done) {
browser
.url('https://localhost/')
.setValue('#userauth_username','foo')
.setValue('#userauth_password',"password")
.submitForm('#form_users_login')
.waitForExist('#auth-user-id')
.getText('#auth-user-id')
.then(function(text){
//console.log('Username: ' + text);
assert.equal(text, 'foo');
})
.saveScreenshot('out.png')
.call(done)
});
it('should not display logincontrols after login', function(done){
browser
.isVisible('#logincontrols')
.then(function(bool){
expect(bool).to.be.false;
})
.call(done)
});
it('should display loggedin section after login', function(done){
browser
.isVisible('#loggedin')
.then(function(bool){
expect(bool).to.be.true;
})
.call(done)
});
});
and for completeness, this is what I see on the output:
# grunt webdriver:chrome
Running "webdriver:chrome" (webdriver) task
login test
✓ verifies user can log in (7691ms)
✓ should not display logincontrols after login (70ms)
✓ should display loggedin section after login (58ms)
3 passing (8s)
Done, without errors.