Skip to content

Commit

Permalink
fix: gherkin supports i18n (#3934)
Browse files Browse the repository at this point in the history
  • Loading branch information
kobenguyent authored Oct 21, 2023
1 parent 01b94fd commit b652bd5
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 1 deletion.
21 changes: 20 additions & 1 deletion lib/interfaces/gherkin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ parser.stopAtFirstError = false;

module.exports = (text, file) => {
const ast = parser.parse(text);
let currentLanguage;

if (ast.feature) {
currentLanguage = getTranslation(ast.feature.language);
}

if (!ast.feature) {
throw new Error(`No 'Features' available in Gherkin '${file}' provided!`);
Expand Down Expand Up @@ -96,7 +101,7 @@ module.exports = (text, file) => {
suite.beforeEach('Before', scenario.injected(async () => runSteps(child.background.steps), suite, 'before'));
continue;
}
if (child.scenario && child.scenario.keyword === 'Scenario Outline') {
if (child.scenario && (currentLanguage ? child.scenario.keyword === currentLanguage.contexts.ScenarioOutline : child.scenario.keyword === 'Scenario Outline')) {
for (const examples of child.scenario.examples) {
const fields = examples.tableHeader.cells.map(c => c.value);
for (const example of examples.tableBody) {
Expand Down Expand Up @@ -162,3 +167,17 @@ function addExampleInTable(exampleSteps, placeholders) {
}
return steps;
}

function getTranslation(language) {
const translations = Object.keys(require('../../translations'));

for (const availableTranslation of translations) {
if (!language) {
break;
}

if (availableTranslation.includes(language)) {
return require('../../translations')[availableTranslation];
}
}
}
17 changes: 17 additions & 0 deletions test/data/sandbox/features/step_definitions/my_steps.de.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const I = actor();

Given('ich habe ein Produkt mit einem Preis von {int}$ in meinem Warenkorb', (price) => {
I.addItem(parseInt(price, 10));
});

Given('der Rabatt für Bestellungen über $\{int} beträgt {int} %', (maxPrice, discount) => { // eslint-disable-line
I.haveDiscountForPrice(maxPrice, discount);
});

When('ich zur Kasse gehe', () => {
I.checkout();
});

Then('sollte ich den Gesamtpreis von "{float}" $ sehen', (price) => {
I.seeSum(price);
});
21 changes: 21 additions & 0 deletions test/data/sandbox/i18n/codecept.bdd.de.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
exports.config = {
tests: './*_no_test.js',
timeout: 10000,
output: '../output',
helpers: {
BDD: {
require: '../support/bdd_helper.js',
},
},
gherkin: {
features: './features/examples.de.feature',
steps: [
'./features/step_definitions/my_steps.de.js',
],
},
include: {},
bootstrap: false,
mocha: {},
name: 'sandbox',
translation: 'de-DE',
};
16 changes: 16 additions & 0 deletions test/data/sandbox/i18n/features/examples.de.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#language: de
Funktionalität: Checkout-Prozess
Um Produkte zu kaufen
Als Kunde
Möchte ich in der Lage sein, mehrere Produkte zu kaufen

@i18n
Szenariogrundriss: Bestellrabatt
Angenommen ich habe ein Produkt mit einem Preis von <price>$ in meinem Warenkorb
Und der Rabatt für Bestellungen über $20 beträgt 10 %
Wenn ich zur Kasse gehe
Dann sollte ich den Gesamtpreis von "<total>" $ sehen

Beispiele:
| price | total |
| 10 | 10.0 |
17 changes: 17 additions & 0 deletions test/data/sandbox/i18n/features/step_definitions/my_steps.de.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const I = actor();

Given('ich habe ein Produkt mit einem Preis von {int}$ in meinem Warenkorb', (price) => {
I.addItem(parseInt(price, 10));
});

Given('der Rabatt für Bestellungen über $\{int} beträgt {int} %', (maxPrice, discount) => { // eslint-disable-line
I.haveDiscountForPrice(maxPrice, discount);
});

When('ich zur Kasse gehe', () => {
I.checkout();
});

Then('sollte ich den Gesamtpreis von "{float}" $ sehen', (price) => {
I.seeSum(price);
});
27 changes: 27 additions & 0 deletions test/runner/bdd_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,31 @@ When(/^I define a step with a \\( paren and a "(.*?)" string$/, () => {
done();
});
});

describe('i18n', () => {
const codecept_dir = path.join(__dirname, '/../data/sandbox/i18n');
const config_run_config = config => `${codecept_run} --config ${codecept_dir}/${config}`;

before(() => {
process.chdir(codecept_dir);
});
it('should run feature files in DE', (done) => {
exec(config_run_config('codecept.bdd.de.js') + ' --steps --grep "@i18n"', (err, stdout, stderr) => { //eslint-disable-line
stdout.should.include('On Angenommen: ich habe ein produkt mit einem preis von 10$ in meinem warenkorb');
stdout.should.include('On Und: der rabatt für bestellungen über $20 beträgt 10 %');
stdout.should.include('On Wenn: ich zur kasse gehe');
stdout.should.include('On Dann: sollte ich den gesamtpreis von "10.0" $ sehen');
stdout.should.include('On Angenommen: ich habe ein produkt mit einem preis von 10$ in meinem warenkorb');
stdout.should.include('Ich add item 10');
stdout.should.include('On Und: der rabatt für bestellungen über $20 beträgt 10 %');
stdout.should.include('Ich have discount for price 20, 10');
stdout.should.include('On Wenn: ich zur kasse gehe');
stdout.should.include('Ich checkout');
stdout.should.include('On Dann: sollte ich den gesamtpreis von "10.0" $ sehen');
stdout.should.include('Ich see sum 10');
assert(!err);
done();
});
});
});
});
5 changes: 5 additions & 0 deletions translations/de-DE.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module.exports = {
I: 'Ich',
contexts: {
Feature: 'Funktionalität',
Scenario: 'Szenario',
ScenarioOutline: 'Szenariogrundriss',
},
actions: {
amOutsideAngularApp: 'befinde_mich_außerhalb_der_angular_app',
amInsideAngularApp: 'bedinde_mich_innerhalb_der_angular_app',
Expand Down
1 change: 1 addition & 0 deletions translations/fr-FR.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
contexts: {
Feature: 'Fonctionnalité',
Scenario: 'Scénario',
ScenarioOutline: 'Plan du scénario',
Before: 'Avant',
After: 'Après',
BeforeSuite: 'AvantLaSuite',
Expand Down
1 change: 1 addition & 0 deletions translations/it-IT.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
contexts: {
Feature: 'Caratteristica',
Scenario: 'lo_scenario',
ScenarioOutline: 'Schema dello scenario',
Before: 'Prima',
After: 'Dopo',
BeforeSuite: 'Prima_della_suite',
Expand Down
5 changes: 5 additions & 0 deletions translations/ja-JP.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module.exports = {
I: '私は',
contexts: {
Feature: 'フィーチャ',
Scenario: 'シナリオ',
ScenarioOutline: 'シナリオアウトライン',
},
actions: {
amOutsideAngularApp: 'Angularの外に出る',
amInsideAngularApp: 'Angularの中に入る',
Expand Down
5 changes: 5 additions & 0 deletions translations/pl-PL.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module.exports = {
I: 'Ja',
contexts: {
Feature: 'Funkcja',
Scenario: 'Scenariusz',
ScenarioOutline: 'Szablon scenariusza',
},
actions: {
amOutsideAngularApp: 'jestem_poza_aplikacją_angular',
amInsideAngularApp: 'jestem_w_aplikacji_angular',
Expand Down
1 change: 1 addition & 0 deletions translations/pt-BR.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
contexts: {
Feature: 'Funcionalidade',
Scenario: 'Cenário',
ScenarioOutline: 'Esquema do Cenário',
Before: 'Antes',
After: 'Depois',
BeforeSuite: 'AntesDaSuite',
Expand Down
1 change: 1 addition & 0 deletions translations/ru-RU.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
contexts: {
Feature: 'Цель',
Scenario: 'Сценарий',
ScenarioOutline: 'Структура сценария',
Before: 'Начало',
After: 'Конец',
BeforeSuite: 'Перед_всем',
Expand Down
5 changes: 5 additions & 0 deletions translations/zh-CN.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module.exports = {
I: '我',
contexts: {
Feature: '功能',
Scenario: '场景',
ScenarioOutline: '场景大纲',
},
actions: {
amOutsideAngularApp: '在Angular应用外',
amInsideAngularApp: '在Angular应用内',
Expand Down
5 changes: 5 additions & 0 deletions translations/zh-TW.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module.exports = {
I: '我',
contexts: {
Feature: '功能',
Scenario: '場景',
ScenarioOutline: '場景大綱',
},
actions: {
amOutsideAngularApp: '在Angular應用外',
amInsideAngularApp: '在Angular應用內',
Expand Down

0 comments on commit b652bd5

Please sign in to comment.