Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a7bf937
Update browser.js
EdStrickland Mar 24, 2020
2e56125
Update browser.js
EdStrickland Mar 25, 2020
b9605f3
Update browser.js
EdStrickland Apr 8, 2020
262a7d9
Merge pull request #1 from SAP/master
EdStrickland Apr 23, 2020
ccdef05
Merge pull request #2 from SAP/master
EdStrickland Apr 23, 2020
377d7ff
add integration tests(unfinished)
EdStrickland Apr 23, 2020
66ef536
Merge pull request #3 from EdStrickland/master
EdStrickland Apr 23, 2020
62ca5db
add integration tests and add config initialization
EdStrickland May 6, 2020
5400109
fix eslint
EdStrickland May 6, 2020
51c331b
Update test/integration/application-log-assersion/webapp/test/Gherkin…
EdStrickland May 28, 2020
dde019c
Update test/integration/application-log-assersion/webapp/test/Website…
EdStrickland May 28, 2020
d0d11d8
Update test/integration/application-log-assersion/karma.conf.js
EdStrickland May 28, 2020
98f551a
enhance config and integration tests
EdStrickland Jun 2, 2020
9d37b93
fix bug`
EdStrickland Jun 2, 2020
58b2d1c
fix gitignore
EdStrickland Jun 2, 2020
7bbaa7a
bug fix
EdStrickland Jun 3, 2020
dadbdec
change ui5 resource to relative path
EdStrickland Jun 3, 2020
cc6117b
simplify mock OPA tests
EdStrickland Jun 9, 2020
d9973f5
simplify mock OPA tests
EdStrickland Jun 9, 2020
72ceeef
fix check
EdStrickland Jun 9, 2020
e9f0660
add the flags in readme
EdStrickland Jun 9, 2020
afe9192
Merge branch 'master' into patch-1
EdStrickland Jul 24, 2020
051d588
Merge branch 'master' into patch-1
EdStrickland Oct 20, 2020
d53933b
fix eslint
EdStrickland Oct 20, 2020
e4469d7
add setTimeout
EdStrickland Oct 20, 2020
ad18be1
testDone should log test module and test name instead of test obj
EdStrickland Oct 23, 2020
63f4485
remove test obj from code
EdStrickland Oct 23, 2020
775545d
fix ui5 tooling iframe path assertion fail on windows
EdStrickland Nov 2, 2020
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ deploy_key

# Custom directories
dist/

cucumber.js
10 changes: 10 additions & 0 deletions lib/client/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ require("./discovery.js");
testResult.success = false;
testResult.errors.push(msg);
}
if (config.logAssertions) {
const result = {
description: details.message,
suite: details.module && [qunitHtmlFile, details.module, details.name, details.message] || [],
success: details.result,
log: testResult.errors || [],
time: new Date().getTime() - timer
};
karma.result(result);
}
});

QUnit.testDone(function(test) {
Expand Down
1 change: 1 addition & 0 deletions lib/framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class Framework {
// Relevant options (e.g. testpage, config, tests) will be written to the client section.
this.config.client.ui5 = {};
this.config.client.ui5.useIframe = true; // for now only allow using iframes in HTML mode
this.config.client.ui5.logAssertions = config.ui5 && config.ui5.logAssertions || false;
this.config.ui5 = config.ui5 || {};
this.config.proxies = config.proxies || {};
this.config.middleware = config.middleware || [];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use strict";

const _ = require("lodash");

module.exports = function(history) {
const cucumberJson = [];

_.forEach(history, function(feature, featureName) {
const elements = [];
const identifier = _.split(featureName, " ");
const tag = identifier[0];
const name = identifier.slice(1).join(" ");

_.forEach(feature, function(scenario, scenarioName) {
elements.push({
name: scenarioName,
type: "scenario",
keyword: "Scenario",
steps: _.map(scenario, function(step) {
return {
keyword: "",
name: step.description,
result: {
duration: step.time * 1000000,
status: step.success ? "passed" : "failed"
}
};
})
});
});

cucumberJson.push({
keyword: "Feature",
name: name,
uri: _.camelCase(name),
tags: [{
name: tag
}],
elements: elements
});
});

return cucumberJson;
};
50 changes: 50 additions & 0 deletions test/integration/application-log-assersion/karma-reporter/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use strict";

const _ = require("lodash");

const formatter = require("./formatter");
const writer = require("./writer");

const CucumberReporter = function(baseReporterDecorator, config, logger, helper) {
const log = logger.create("reporter.cucumber");
const reporterConfig = config.cucumberReporter || {};
const out = reporterConfig.out || "stdout";
const history = {};

baseReporterDecorator(this);

this.adapters = [function(msg) {
process.stdout.write.bind(process.stdout)(msg);
}];

this.onSpecComplete = function(browser, result) {
const suite = result.suite[1];
const scenario = result.description;
const step = result.suite[3];

if (!reporterConfig.prefix || reporterConfig.prefix && _.startsWith(suite, reporterConfig.prefix)) {
history[suite] = history[suite] || {};
history[suite][scenario] = history[suite][scenario] || [];
if (step) {
history[suite][scenario].push(result);
}
}
};

this.onRunComplete = function() {
const cucumberJson = formatter(history);
const jsonResult = JSON.stringify(cucumberJson, null, 2) + "\n";

if (out === "stdout") {
process.stdout.write(jsonResult);
} else {
writer(helper, out, log, jsonResult);
}
};
};

CucumberReporter.$inject = ["baseReporterDecorator", "config", "logger", "helper", "formatError"];

module.exports = {
"reporter:cucumber": ["type", CucumberReporter]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use strict";

const path = require("path");
const fs = require("fs");

module.exports = function(helper, out, log, jsonResult) {
helper.mkdirIfNotExists(path.dirname(out), function() {
fs.writeFile(out, jsonResult, function(err) {
if (err) {
log.error("Cannot write JSON\n\t" + err.message);
} else {
log.info("JSON written to %s", out);
}
});
});
};
67 changes: 67 additions & 0 deletions test/integration/application-log-assersion/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const customCucumberReporter = require("./karma-reporter/index");
const customKarmaUI5 = require("../../../lib/index");

module.exports = function(config) {
"use strict";

require("../karma-base.conf")(config);
config.set({
plugins: [
"karma-chrome-launcher",
"karma-coverage",
customKarmaUI5,
customCucumberReporter
],

ui5: {
type: "application",
mode: "html",
testpage: "webapp/test/GherkinTestRunner.html",
url: "http://localhost:" + config.localUI5ServerPort,
logAssertions: true
},

frameworks: ["ui5"],

preprocessors: {
"{webapp,webapp/!(test)}/*.js": ["coverage"]
},
cucumberReporter: {
out: "application-log-assersion/cucumber.json",
prefix: ""
},

coverageReporter: {
includeAllSources: true,
reporters: [
{
type: "json",
dir: "coverage",
subdir: "json"
}
],
check: {
each: {
statements: 100,
branches: 100,
functions: 100,
lines: 100
}
}
},
autoWatch: false,
singleRun: true,

reporters: ["progress", "coverage", "cucumber"]

});
};

module.exports.assertions = function({expect, log}) {
const features = require("./cucumber.json");
const scenarios = features[0].elements;
const steps = scenarios[0].steps;
expect(features).toHaveLength(1);
expect(scenarios).toHaveLength(12);
expect(steps).toHaveLength(2);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Using Gherkin with OPA5</title>

<script
id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-resourceroots='{"GherkinWithOPA5": "./"}'
data-sap-ui-async="true"
data-sap-ui-loglevel="INFO"
></script>

<script src="GherkinTestRunner.js"></script>

</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>



Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* global QUnit */
window.QUnit = {
config: {
autostart: false
}
};

sap.ui.require([
"sap/ui/test/gherkin/opa5TestHarness",
// Code coverage will be calculated for all modules loaded after the harness
"GherkinWithOPA5/Steps"
], function(opa5TestHarness, Steps) {
"use strict";

opa5TestHarness.test({
featurePath: "GherkinWithOPA5.Requirements1",
steps: Steps
});

QUnit.start();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Feature: Clicking Buttons Is a Life Saving Activity
Clicking buttons saves lemmings' lives. For the mere cost of a cheap home PC you
can save thousands of lemmings daily by clicking buttons all day long.

Background:
Given I have started the app
And I can see the life saving button

Scenario: Click a button, save a life!
Given I check how many lemmings have been saved already
When I click on the life saving button
Then I save a lemming's life

Scenario: The saved lemming has a name
When I click on the life saving button
Then I see Alice at the end of the list of named lemmings

@wip
Scenario: Lemmings don't really throw themselves off cliffs
Given there was a documentary of lemmings throwing themselves off a cliff
Given this film greatly affected people's perception of lemmings
Given this part of the film was faked
Then we expect the myth of suicide lemmings to persist despite its falsity
101 changes: 101 additions & 0 deletions test/integration/application-log-assersion/webapp/test/Steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
sap.ui.define([
"sap/base/Log",
"sap/ui/test/gherkin/StepDefinitions",
"sap/ui/test/Opa5",
"sap/ui/test/actions/Press"
], function(Log, StepDefinitions, Opa5, Press) {
"use strict";

const oOpa5 = new Opa5();

/**
* @param {Function} fnCallback - executed once the number of lemmings saved is determined.
* Receives one parameter: "iNumberOfLemmingsSaved"
*/
function getNumberOfLemmingsSaved(fnCallback) {
oOpa5.waitFor({
id: "num-lemmings-saved",
success: function(oLabel) {
const sNumberOfLemmingsSaved = oLabel.getText().match(/Number of lemmings saved: (\d+)/)[1];
const iNumberOfLemmingsSaved = parseInt(sNumberOfLemmingsSaved);
fnCallback(iNumberOfLemmingsSaved);
}
});
}

const Steps = StepDefinitions.extend("GherkinWithOPA5.Steps", {
init: function() {
this.register(/^I have started the app$/i, function() {
oOpa5.iStartMyAppInAFrame(sap.ui.require.toUrl("GherkinWithOPA5/Website.html"));
});

this.register(/^I can see the life saving button$/i, function() {
oOpa5.waitFor({
id: "life-saving-button",
success: function(oButton) {
Opa5.assert.strictEqual(oButton.getText(), "Save a Lemming",
"Verified that we can see the life saving button");
}
});
});

this.register(/^I check how many lemmings have been saved already$/i, function() {
getNumberOfLemmingsSaved(function(iNumberOfLemmingsSaved) {
this.iNumLemmings = iNumberOfLemmingsSaved;
/* eslint-disable */
}.bind(this));
/* eslint-enable */
});

this.register(/^I click on the life saving button\s*(\d*)?(?:\s*times)?$/i, function(sNumTimes) {
const iNumTimes = (sNumTimes) ? parseInt(sNumTimes) : 1;
for (let i = 0; i < iNumTimes; ++i) {
oOpa5.waitFor({
id: "life-saving-button",
actions: new Press()
});
}
});

this.register(/^I save a lemming's life$/i, function() {
getNumberOfLemmingsSaved(function(iNumberOfLemmingsSaved) {
const iExpectedSavedLemmings = this.iNumLemmings + 1;
Opa5.assert.strictEqual(iNumberOfLemmingsSaved, iExpectedSavedLemmings,
"Verified correct number of lemmings saved");
/* eslint-disable */
}.bind(this));
/* eslint-enable */
});

this.register(/^I can see the following named lemmings:$/i, function(aDataTable) {
aDataTable.forEach(function(sLemmingName, iLemmingId) {
oOpa5.waitFor({
id: "lemming-name-" + (iLemmingId + 1),
success: function(oLabel) {
Opa5.assert.strictEqual(oLabel.getText(), sLemmingName,
"Verified lemming: " + sLemmingName);
}
});
});
});

this.register(/^I see (\w+) at the end of the list of named lemmings$/i, function(sName) {
oOpa5.waitFor({
id: "layout",
success: function(oLayout) {
const aContent = oLayout.getContent();
const oLastContentItem = aContent[aContent.length - 1];
Opa5.assert.strictEqual(oLastContentItem.getText(), sName,
"Verified lemming: " + sName);
}
});
});
},

closeApplication: function() {
Log.info("Closing application");
}
});

return Steps;
});
Loading