Skip to content
This repository was archived by the owner on Jul 30, 2022. It is now read-only.

chore(protractor-typescript-cucumber):cucumber 3.x support #39

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
machine:
node:
version: 7.5.0
version: 8.9.1
environment:
# Fix issue with selenium-server in containers.
# See http://github.com/SeleniumHQ/docker-selenium/issues/87
Expand Down
3 changes: 2 additions & 1 deletion protractor-typescript-cucumber/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode/
node_modules/
tmp/
typeScript/
reports/
40 changes: 30 additions & 10 deletions protractor-typescript-cucumber/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
###Protractor-Cucumber-TypeScript Setup Guide
## Protractor-Cucumber-TypeScript Setup Guide

This project demonstrates the basic protractor-cucumber-typescript framework project setup.

###Features
### Features

* No typings.json or typings folder, they have been replaced by better **'@types'** modules in package.json
* ts-node(typescript execution environment for node) in cucumberOpts.
* All scripts written with Typescript2.0 & Cucumber2.0
Expand All @@ -11,25 +12,29 @@ This project demonstrates the basic protractor-cucumber-typescript framework pro
* Extensive hooks implemented for BeforeFeature, AfterScenarios etc.
* Screenshots on failure feature scenarios

### To Get Started

###To Get Started
#### Pre-requisites

####Pre-requisites
1.NodeJS installed globally in the system.
https://nodejs.org/en/download/

2.Chrome or Firefox browsers installed.

3.Text Editor(Optional) installed-->Sublime/Visual Studio Code/Brackets.

####Setup Scripts
#### Setup Scripts

* run following command from terminal/command prompt

```
npm install
npm install
```

* All the dependencies from package.json and ambient typings would be installed in node_modules folder.

####Setup & Run TestApp
#### Setup & Run TestApp

```
cd ..
cd testapp/
Expand All @@ -38,13 +43,28 @@ cd testapp/

npm start
```
#### Start Selenium Server

```
npm run webdriver-update && npm run webdriver-start
```

#### Run Scripts

####Run Scripts
```
npm test
npm test
```

* The above command should create an output folder named 'tmp' and transpile the .ts files.
* It launches the Firefox Browser and run the scripts

##Contributions
### Report

**json** & **html** reports are auto-generated in the `reports` folder when you run `npm test`. Currently this project has been integrated with [cucumber-html-reporter](https://github.com/gkushang/cucumber-html-reporter).
They can be customized according to user's specific needs.

<img src='./images/report.png' alt='report.png'>

## Contributions

For contributors who want to improve this repo by contributing some code, reporting bugs, issues or improving documentation - PR's are highly welcome, please maintain the coding style , folder structure , detailed description of documentation and bugs/issues with examples if possible.
23 changes: 16 additions & 7 deletions protractor-typescript-cucumber/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { environment } from './environment';
import { browser, Config } from 'protractor';
import { Reporter } from '../support/reporter';
import { environment } from './environment';
const jsonReports = process.cwd() + '/reports/json';

/*
The config folder includes all the configuration files
Expand All @@ -12,21 +14,28 @@ export let config: Config = {
baseUrl: environment.baseUrl,
capabilities: environment.capabilities,
framework: 'custom',
SELENIUM_PROMISE_MANAGER: false,
frameworkPath: require.resolve('protractor-cucumber-framework'),

specs: [
'../../features/*.feature'
'../../features/*.feature',
],
// This utility function helps prepare our scripts with required actions like browser maximize
onPrepare: () => {
browser.driver.manage().window().maximize();
Reporter.createDirectory(jsonReports);
},
// These are various cucumber compiler options
cucumberOpts: {
compiler: "ts:ts-node/register",
format: ["pretty"],
compiler: 'ts:ts-node/register',
format: 'json:./reports/json/cucumber_report.json',
require: ['../../stepdefinitions/*.ts', '../../support/*.ts'],
//tags help us execute specific scenarios of feature files
tags: '@AddScenario or @SubtractScenario or @MultiplyScenario or @DivideScenario or @ModulusScenario'
}
strict: true,
// tags help us execute specific scenarios of feature files
tags: '@AddScenario or @SubtractScenario or @MultiplyScenario or @DivideScenario or @ModulusScenario',
},

onComplete: () => {
Reporter.createHTMLReport();
},
};
12 changes: 6 additions & 6 deletions protractor-typescript-cucumber/config/environment.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
let webServerDefaultPort = 8080;
const port = 8080;

export let environment = {
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName':
browserName:
(process.env.TEST_BROWSER_NAME || 'chrome'),
'version':
(process.env.TEST_BROWSER_VERSION || 'ANY')
version:
(process.env.TEST_BROWSER_VERSION || 'ANY'),
},

// Default http port to host the web server
webServerDefaultPort: webServerDefaultPort,
webServerDefaultPort: port,

// Protractor interactive tests
interactiveTestPort: 6969,

// A base URL for your application under test.
baseUrl:
'http://' + (process.env.HTTP_HOST || 'localhost') +
':' + (process.env.HTTP_PORT || webServerDefaultPort)
':' + (process.env.HTTP_PORT || port),

};
Binary file added protractor-typescript-cucumber/images/report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 20 additions & 15 deletions protractor-typescript-cucumber/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,29 @@
"automation testing"
],
"scripts": {
"example": "protractor tmp/config/config.js",
"pretest": "npm run tsc",
"clean": "rimraf typeScript/",
"clean-build": "npm run clean && npm run tsc",
"example": "protractor typeScript/config/config.js",
"pretest": "npm run clean-build",
"test": "npm run example",
"tsc": "tsc"
"tsc": "tsc",
"webdriver-update": "webdriver-manager update",
"webdriver-start": "webdriver-manager start"
},
"author": "Ram Pasala <ram.pasala7@gmail.com>",
"dependencies": {
"protractor": "^5.1.1",
"ts-node": "^2.1.0",
"typescript": "^2.2.1"
},
"devDependencies": {
"@types/cucumber": "^0.0.38",
"@types/node": "^7.0.8",
"@types/selenium-webdriver": "~2.53.39",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"cucumber": "^2.0.0-rc.8",
"protractor-cucumber-framework": "^1.0.1"
"@types/cucumber": "^2.0.4",
"@types/node": "^8.0.51",
"@types/selenium-webdriver": "^3.0.8",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"cucumber": "^3.1.0",
"cucumber-html-reporter": "^3.0.4",
"mkdirp": "^0.5.1",
"protractor": "^5.2.0",
"protractor-cucumber-framework": "^4.1.1",
"rimraf": "^2.6.2",
"ts-node": "^3.3.0",
"typescript": "^2.6.1"
}
}
26 changes: 14 additions & 12 deletions protractor-typescript-cucumber/pages/calcPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import { $, by, element, ElementFinder } from 'protractor';
Page Objects help in better re-usablitity and maintenance of element locators
This file exports CalculatorPageObject class
**/
export class CalculatorPageObject {
public first_operand:ElementFinder;
public second_operand:ElementFinder;
class CalculatorPageObject {
public get firstOperand(): ElementFinder { return element(by.model('first')); }
public get secondOperand(): ElementFinder { return element(by.model('second')); }
public get goButton(): ElementFinder { return element(by.id('gobutton')); }
public get result(): ElementFinder { return element(by.binding('latest')); }
public operator: any;
public go_button: ElementFinder;
public result: ElementFinder;

constructor() {
this.first_operand = element(by.model('first'));
this.second_operand = element(by.model('second'));
this.operator = (optor:string) => {
return element(by.cssContainingText('option',optor));
}
this.go_button = element(by.id('gobutton'));
this.result = element(by.binding('latest'));
this.operator = (optor: string) => {
return element(by.cssContainingText('option', optor));
};
}
}

/**
* Export the instance of page objects in order to
* reduce flakiness and stateless priciple
*/
export const CalculatorPage = new CalculatorPageObject();
36 changes: 16 additions & 20 deletions protractor-typescript-cucumber/stepdefinitions/calcSteps.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { browser } from 'protractor';
import { CalculatorPageObject } from '../pages/calcPage';
import { defineSupportCode } from 'cucumber';
let chai = require('chai').use(require('chai-as-promised'));
let expect = chai.expect;
import { CalculatorPage } from '../pages/calcPage';
const {Given, When, Then} = require('cucumber');
const chai = require('chai').use(require('chai-as-promised'));
const expect = chai.expect;
/*
StepDefinition files act as the glue code between config and feature files
They drive the feature files from the background
**/
defineSupportCode(({Given, When, Then}) => {
let calc: CalculatorPageObject = new CalculatorPageObject();

Given(/^I am on ng1 calculator page$/, () => {
return expect(browser.getTitle()).to.eventually.equal('Super Calculator');
});
Given(/^I am on ng1 calculator page$/, async () => {
await expect(browser.getTitle()).to.eventually.equal('Super Calculator');
});

When(/^I calculate "(.*?)" "(.*?)" "(.*?)"$/, (num1: string, optor: string, num2: string) => {
calc.first_operand.sendKeys(num1);
calc.operator(optor).click();
calc.second_operand.sendKeys(num2);
return calc.go_button.click();
});

Then(/^the result "(.*?)" should be displayed$/, (result: string) => {
return expect(calc.result.getText()).to.eventually.equal(result);
});
})
When(/^I calculate "(.*?)" "(.*?)" "(.*?)"$/, async (num1: string, optor: string, num2: string) => {
await CalculatorPage.firstOperand.sendKeys(num1);
await CalculatorPage.operator(optor).click();
await CalculatorPage.secondOperand.sendKeys(num2);
await CalculatorPage.goButton.click();
});

Then(/^the result "(.*?)" should be displayed$/, async (result: string) => {
await expect(CalculatorPage.result.getText()).to.eventually.equal(result);
});
31 changes: 12 additions & 19 deletions protractor-typescript-cucumber/support/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
/*jslint node: true*/
import { browser } from 'protractor';
import { defineSupportCode } from "cucumber";
const { BeforeAll, After, setDefaultTimeout, Status } = require('cucumber');
import * as fs from 'fs';
/*
Hooks help us follow DRY principle, all the utility functions go here
BeforeScenario, Features and screenshot hooks example provided here
**/
defineSupportCode(function ({registerHandler, After}) {
setDefaultTimeout(10 * 1000);

registerHandler('BeforeFeature', (event) => {
return browser.get('/ng1/calculator');
});
BeforeAll(async () => {
await browser.get('/ng1/calculator');
});

After((scenario, done) => {
if (scenario.isFailed()) {
return browser.takeScreenshot().then(function (base64png) {
let decodedImage = new Buffer(base64png, 'base64').toString('binary');
scenario.attach(decodedImage, 'image/png');
}, (err) => {
done(err);
});
} else {
done();
}
});
})
After(async (scenario) => {
if (scenario.result.status === Status.FAILED) {
// screenShot is a base-64 encoded PNG
const screenShot = await browser.takeScreenshot();
this.attach(screenShot, 'image/png');
}
});
33 changes: 33 additions & 0 deletions protractor-typescript-cucumber/support/reporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as reporter from 'cucumber-html-reporter';
import * as fs from 'fs';
import * as mkdirp from 'mkdirp';
import * as path from 'path';
const jsonReports = path.join(process.cwd(), '/reports/json');
const htmlReports = path.join(process.cwd(), '/reports/html');
const targetJson = jsonReports + '/cucumber_report.json';

const cucumberReporterOptions = {
jsonFile: targetJson,
output: htmlReports + '/cucumber_reporter.html',
reportSuiteAsScenarios: true,
theme: 'bootstrap',
};

export class Reporter {

public static createDirectory(dir: string) {
if (!fs.existsSync(dir)) {
mkdirp.sync(dir);
}
}

public static createHTMLReport() {
try {
reporter.generate(cucumberReporterOptions); // invoke cucumber-html-reporter
} catch (err) {
if (err) {
throw new Error('Failed to save cucumber test results to json file.');
}
}
}
}
5 changes: 3 additions & 2 deletions protractor-typescript-cucumber/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
"declaration": false,
"removeComments": false,
"noImplicitAny": false,
"outDir": "tmp",
"outDir": "typeScript",
"typeRoots": [
"./node_modules/@types"
],
"types": [
"node",
"cucumber"
"cucumber",
"selenium-webdriver"
]
},
"exclude": [
Expand Down
Loading