diff --git a/lib/interfaces/gherkin.js b/lib/interfaces/gherkin.js index 1b09c3a9c..65f8dedd0 100644 --- a/lib/interfaces/gherkin.js +++ b/lib/interfaces/gherkin.js @@ -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!`); @@ -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) { @@ -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]; + } + } +} diff --git a/test/data/sandbox/codecept.bdd.de.js b/test/data/sandbox/codecept.bdd.de.js new file mode 100644 index 000000000..bdae8b3f2 --- /dev/null +++ b/test/data/sandbox/codecept.bdd.de.js @@ -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', +}; diff --git a/test/data/sandbox/features/examples.de.feature b/test/data/sandbox/features/examples.de.feature new file mode 100644 index 000000000..b1f13cd4f --- /dev/null +++ b/test/data/sandbox/features/examples.de.feature @@ -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 @fail + Szenariogrundriss: Bestellrabatt + Angenommen ich habe ein Produkt mit einem Preis von $ 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 "" $ sehen + + Beispiele: + | price | total | + | 10 | 10.0 | diff --git a/test/data/sandbox/features/step_definitions/my_steps.de.js b/test/data/sandbox/features/step_definitions/my_steps.de.js new file mode 100644 index 000000000..0fdc12f1c --- /dev/null +++ b/test/data/sandbox/features/step_definitions/my_steps.de.js @@ -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); +}); diff --git a/test/runner/bdd_test.js b/test/runner/bdd_test.js index f153a50aa..cd010b766 100644 --- a/test/runner/bdd_test.js +++ b/test/runner/bdd_test.js @@ -305,4 +305,25 @@ When(/^I define a step with a \\( paren and a "(.*?)" string$/, () => { done(); }); }); + + describe('i18n', () => { + 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(); + }); + }); + }); }); diff --git a/translations/de-DE.js b/translations/de-DE.js index e44a39e9f..8d2da5be0 100644 --- a/translations/de-DE.js +++ b/translations/de-DE.js @@ -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', diff --git a/translations/fr-FR.js b/translations/fr-FR.js index d9042a1ad..0e3eadb00 100644 --- a/translations/fr-FR.js +++ b/translations/fr-FR.js @@ -3,6 +3,7 @@ module.exports = { contexts: { Feature: 'Fonctionnalité', Scenario: 'Scénario', + ScenarioOutline: 'Plan du scénario', Before: 'Avant', After: 'Après', BeforeSuite: 'AvantLaSuite', diff --git a/translations/it-IT.js b/translations/it-IT.js index ab769e964..f0c84a303 100644 --- a/translations/it-IT.js +++ b/translations/it-IT.js @@ -3,6 +3,7 @@ module.exports = { contexts: { Feature: 'Caratteristica', Scenario: 'lo_scenario', + ScenarioOutline: 'Schema dello scenario', Before: 'Prima', After: 'Dopo', BeforeSuite: 'Prima_della_suite', diff --git a/translations/ja-JP.js b/translations/ja-JP.js index 51259e048..03e948ebf 100644 --- a/translations/ja-JP.js +++ b/translations/ja-JP.js @@ -1,5 +1,10 @@ module.exports = { I: '私は', + contexts: { + Feature: 'フィーチャ', + Scenario: 'シナリオ', + ScenarioOutline: 'シナリオアウトライン', + }, actions: { amOutsideAngularApp: 'Angularの外に出る', amInsideAngularApp: 'Angularの中に入る', diff --git a/translations/pl-PL.js b/translations/pl-PL.js index 0c69b1596..e64a15844 100644 --- a/translations/pl-PL.js +++ b/translations/pl-PL.js @@ -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', diff --git a/translations/pt-BR.js b/translations/pt-BR.js index befd770d4..5f54fdb8b 100644 --- a/translations/pt-BR.js +++ b/translations/pt-BR.js @@ -3,6 +3,7 @@ module.exports = { contexts: { Feature: 'Funcionalidade', Scenario: 'Cenário', + ScenarioOutline: 'Esquema do Cenário', Before: 'Antes', After: 'Depois', BeforeSuite: 'AntesDaSuite', diff --git a/translations/ru-RU.js b/translations/ru-RU.js index 15399b880..f08d1103b 100644 --- a/translations/ru-RU.js +++ b/translations/ru-RU.js @@ -3,6 +3,7 @@ module.exports = { contexts: { Feature: 'Цель', Scenario: 'Сценарий', + ScenarioOutline: 'Структура сценария', Before: 'Начало', After: 'Конец', BeforeSuite: 'Перед_всем', diff --git a/translations/zh-CN.js b/translations/zh-CN.js index 5364bae76..30aef2636 100644 --- a/translations/zh-CN.js +++ b/translations/zh-CN.js @@ -1,5 +1,10 @@ module.exports = { I: '我', + contexts: { + Feature: '功能', + Scenario: '场景', + ScenarioOutline: '场景大纲', + }, actions: { amOutsideAngularApp: '在Angular应用外', amInsideAngularApp: '在Angular应用内', diff --git a/translations/zh-TW.js b/translations/zh-TW.js index b633aa2f4..bb13b4bf4 100644 --- a/translations/zh-TW.js +++ b/translations/zh-TW.js @@ -1,5 +1,10 @@ module.exports = { I: '我', + contexts: { + Feature: '功能', + Scenario: '場景', + ScenarioOutline: '場景大綱', + }, actions: { amOutsideAngularApp: '在Angular應用外', amInsideAngularApp: '在Angular應用內',