From 889520c602aa991c1fe693150e24b1cf400dc601 Mon Sep 17 00:00:00 2001 From: Billel Attouchi Date: Fri, 2 Mar 2018 22:12:22 +0100 Subject: [PATCH] feat(snapshot): add snapshot support for Scenario Outline --- README.md | 2 +- .../__snapshots__/snapshot.feature.snap | 14 +++++ examples/features/snapshot/snapshot.feature | 20 +++++++ src/extensions/snapshot/snapshot.js | 56 ++++++++++++++++++- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 095a4bca..7aa7125e 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ It's also the perfect companion for testing CLI applications built with commande - [**http API**](#http-api-extension) [install](#http-api-installation) | [gherkin expressions](#http-api-gherkin-expressions) | [low level API](#http-api-low-level-api) - [**CLI**](#cli-extension) [install](#cli-installation) | [gherkin expressions](#cli-gherkin-expressions) | [low level API](#cli-low-level-api) - [**fileSystem**](#file-system-extension) [install](#file-system-installation) | [gherkin expressions](#file-system-gherkin-expressions) | [low level API](#file-system-low-level-api) - - [**snapshot**](#snapshot-extension) [install](#snapshot-installation) | [low level API](#snapshot-low-level-api) + - [**snapshot**](#snapshot-extension) [install](#snapshot-extension-installation) | [low level API](#snapshot-low-level-api) - [Helpers](#helpers) - [**cast**](#cast-helper) [usage](#cast-usage) | [add a type](#add-a-type) - [Examples](#examples) diff --git a/examples/features/snapshot/__snapshots__/snapshot.feature.snap b/examples/features/snapshot/__snapshots__/snapshot.feature.snap index 8cca0bda..4250eb07 100644 --- a/examples/features/snapshot/__snapshots__/snapshot.feature.snap +++ b/examples/features/snapshot/__snapshots__/snapshot.feature.snap @@ -1,5 +1,13 @@ +exports[`Scenario Outline 1.1`] = `undefined`; + +exports[`Scenario Outline 2.1`] = `undefined`; + +exports[`Scenario Outline 3.1`] = `undefined`; + +exports[`Scenario Outline 4.1`] = `undefined`; + exports[`Setting json body from .yaml fixture file 1.1`] = `Object { "first_name": "Raphaël", "gender": "male", @@ -22,3 +30,9 @@ first_name: Raphaël last_name: Benitte gender: male "`; + +exports[`Snapshot testing on files 2.1`] = `"id: 1 +first_name: Raphaël +last_name: Benitte +gender: male +"`; diff --git a/examples/features/snapshot/snapshot.feature b/examples/features/snapshot/snapshot.feature index 82218472..a8faac88 100644 --- a/examples/features/snapshot/snapshot.feature +++ b/examples/features/snapshot/snapshot.feature @@ -15,3 +15,23 @@ Feature: Using snapshot definitions Scenario: Snapshot testing on files Given I set cwd to examples/features/snapshot/fixtures Then file file.yaml should match snapshot + + Scenario Outline: I get all posts filtered using '=' directive + Given I mock http call to forward request body for path /users/yaml + When I POST http://fake.io/users/yaml + Then response status code should be 200 + And response body should match snapshot + + Examples: + | filter | value | + + | title | car industry | + + | anotherTitle | antother value | + # this comment and the empty lines above and below shouldn't be taken into account + + + | tester | tesfdkngjsfk | + Scenario: Snapshot testing on files + Given I set cwd to examples/features/snapshot/fixtures + Then file file.yaml should match snapshot diff --git a/src/extensions/snapshot/snapshot.js b/src/extensions/snapshot/snapshot.js index ea079510..6ea91a0f 100644 --- a/src/extensions/snapshot/snapshot.js +++ b/src/extensions/snapshot/snapshot.js @@ -17,7 +17,8 @@ const EXPECTED_COLOR = chalk.green const RECEIVED_COLOR = chalk.red exports.scenarioRegex = /^[\s]*Scenario:[\s]*(.*[^\s])[\s]*$/ - +exports.examplesRegex = /^[\s]*Examples:[\s]*$/ +exports.oneExampleRegex = /\|(.*)\|/ /** * Extract scenarios from a feature file * @param {string} file - Feature file path @@ -32,15 +33,68 @@ exports.extractScenarios = file => { const linesContent = _.split(content, '\n') let result = [] + let skipToIndex = -1 + _.forEach(linesContent, (lineContent, idx) => { + //In the case of a Scenario Outline, skip to its end after it has been processed + if (skipToIndex > 0) { + if (skipToIndex === idx) { + skipToIndex = -1 + } else { + return + } + } + const line = idx + 1 const scenarioInfos = this.scenarioRegex.exec(lineContent) if (scenarioInfos) result.push({ line, name: scenarioInfos[1] }) + + const scenarioOutlineInfo = this.examplesRegex.exec(lineContent) + if (scenarioOutlineInfo) { + const examples = extractExampleLines( + _.slice(linesContent, idx + 1), + idx + 2, + scenarioOutlineInfo[1] + ) + result.push(...examples.results) + } }) return result } +/** + * A function to extract the lines of examples in the Scenario outline + * + * @param {Array} examplesLinesContent - The remaining lines to be examined and parsed + * @param {number} offset - The index of the first line in the original text + * @param {String} name - the name for the scenarios + * @returns {{results: Array, endIndex: *}} + */ +const extractExampleLines = (examplesLinesContent, offset, name = 'Scenario Outline') => { + const results = [] + let endIndex = offset + let headersSkipped = false + + _.forEach(examplesLinesContent, (lineContent, idx) => { + if (lineContent.match(/^\s*$/) || lineContent.match(/[\s]*#.*/)) return //skip empty lines and comments + const index = offset + idx + endIndex = index + const example = this.oneExampleRegex.exec(lineContent) + if (example) { + if (headersSkipped) { + results.push({ line: index, name }) + } else { + headersSkipped = true + } + } else { + return false //break out of the loop + } + }) + + return { results, endIndex } +} + /** * Create snapshots prefix that will be used for each snapshot step of a scenario * For example if the scenario name is 'Scenario 1', then prefix will be 'Scenario 1 1'