Skip to content

Commit

Permalink
Correctly filter test cases when using omitFiltered
Browse files Browse the repository at this point in the history
This fixes #1018 [1].

[1] #1018
  • Loading branch information
badeball committed May 18, 2023
1 parent a499f76 commit d72224a
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 44 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.

- Allow generation of JSON reports with hooks (After / Before) even if `baseUrl` is undefined, fixes [#1017](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1017).

- Correctly filter test cases in HTML reports when using `omitFiltered`, fixes [#1018](https://github.com/badeball/cypress-cucumber-preprocessor/issues/1018).

## v17.1.0

- Add support for (testing) type-specific configuration, fixes [#700](https://github.com/badeball/cypress-cucumber-preprocessor/issues/700).
Expand Down
84 changes: 84 additions & 0 deletions features/reporters/html.feature
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,87 @@ Feature: html report
When I run cypress
Then it passes
And the report should display when last run

Rule: it should obey `omitFiltered`
Background:
Given additional preprocessor configuration
"""
{
"omitFiltered": true
}
"""

Scenario: without tags
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
Scenario: a scenario
Given a step
Scenario: another scenario
Given a step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a step", function() {})
"""
When I run cypress
Then it should appear as if both tests ran
And the HTML should display 2 executed scenarios

Scenario: with user-provided tags
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
@foobar
Scenario: a scenario
Given a step
Scenario: another scenario
Given a step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a step", function() {})
"""
When I run cypress with "--env tags=@foobar"
Then it should appear as if only a single test ran
And the HTML should display 1 executed scenario

Scenario: @focus
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
@focus
Scenario: a scenario
Given a step
Scenario: another scenario
Given a step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a step", function() {})
"""
When I run cypress
Then it should appear as if only a single test ran
And the HTML should display 1 executed scenario

Scenario: @skip
Given a file named "cypress/e2e/a.feature" with:
"""
Feature: a feature
Scenario: a scenario
Given a step
@skip
Scenario: another scenario
Given a step
"""
And a file named "cypress/support/step_definitions/steps.js" with:
"""
const { Given } = require("@badeball/cypress-cucumber-preprocessor");
Given("a step", function() {})
"""
When I run cypress
Then it should appear as if only a single test ran
And the HTML should display 1 executed scenario
45 changes: 35 additions & 10 deletions features/step_definitions/html_steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,48 @@ Then("the report should display when last run", async function () {
{ runScripts: "dangerously" }
);

const dt = Array.from(dom.window.document.querySelectorAll("dt")).find(
(el) => el.textContent === "last run"
const dt = assertAndReturn(
Array.from(dom.window.document.querySelectorAll("dt")).find(
(el) => el.textContent === "last run"
),
"Expected to find a 'last run' dt"
);

assert(dt, "Expected to find a 'last run' dt");

const dd = dt.parentElement?.querySelector("dd");

assert(dd, "Expected to find a 'last run' dt's dd");

const lastRunText = dd.textContent;
const dd = assertAndReturn(
dt.parentElement?.querySelector("dd"),
"Expected to find a 'last run' dt's dd"
);

assert(lastRunText, "Expected to find 'XX seconds ago'");
const lastRunText = assertAndReturn(
dd.textContent,
"Expected to find 'XX seconds ago'"
);

assert.match(lastRunText, /\d+ seconds? ago/);
});

Then(
"the HTML should display {int} executed scenario(s)",
async function (n: number) {
const dom = await JSDOM.fromFile(
path.join(this.tmpDir, "cucumber-report.html"),
{ runScripts: "dangerously" }
);

const dt = assertAndReturn(
Array.from(dom.window.document.querySelectorAll("dt")).find(
(el) => el.textContent && /\d+ executed/.test(el.textContent)
),
"Expected to find a 'XX executed' dt"
);

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const actual = parseInt(dt.textContent!, 10);

assert.equal(actual, n);
}
);

Then("the report should have an image attachment", async function () {
const dom = await JSDOM.fromFile(
path.join(this.tmpDir, "cucumber-report.html"),
Expand Down
78 changes: 44 additions & 34 deletions lib/browser-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ function createPickle(context: CompositionContext, pickle: messages.Pickle) {
...afterHooks.map((hook) => ({ hook })),
];

if (!testFilter.evaluate(tags) || tags.includes("@skip")) {
if (shouldSkipPickle(testFilter, pickle)) {
if (!context.omitFiltered) {
it.skip(scenarioName);
}
Expand Down Expand Up @@ -565,6 +565,12 @@ function createTestFilter(
}
}

function shouldSkipPickle(testFilter: Node, pickle: messages.Pickle) {
const tags = collectTagNames(pickle.tags);

return !testFilter.evaluate(tags) || tags.includes("@skip");
}

function beforeHandler(context: CompositionContext) {
if (!retrieveInternalSuiteProperties()?.isEventHandlersAttached) {
fail(
Expand Down Expand Up @@ -749,6 +755,8 @@ export default function createTests(

registry.finalize(newId);

const testFilter = createTestFilter(gherkinDocument, Cypress.env());

const stepDefinitions: messages.StepDefinition[] =
registry.stepDefinitions.map((stepDefinition) => {
const type: messages.StepDefinitionPatternType =
Expand All @@ -766,42 +774,46 @@ export default function createTests(
};
});

const testCases: messages.TestCase[] = pickles.map((pickle) => {
const tags = collectTagNames(pickle.tags);
const beforeHooks = registry.resolveBeforeHooks(tags);
const afterHooks = registry.resolveAfterHooks(tags);

const hooksToStep = (hook: IHook): messages.TestStep => {
return {
id: hook.id,
hookId: hook.id,
const testCases: messages.TestCase[] = pickles
.filter((pickle) => {
return !omitFiltered || !shouldSkipPickle(testFilter, pickle);
})
.map((pickle) => {
const tags = collectTagNames(pickle.tags);
const beforeHooks = registry.resolveBeforeHooks(tags);
const afterHooks = registry.resolveAfterHooks(tags);

const hooksToStep = (hook: IHook): messages.TestStep => {
return {
id: hook.id,
hookId: hook.id,
};
};
};

const pickleStepToTestStep = (
pickleStep: messages.PickleStep
): messages.TestStep => {
const stepDefinitionIds = registry
.getMatchingStepDefinitions(pickleStep.text)
.map((stepDefinition) => stepDefinition.id);
const pickleStepToTestStep = (
pickleStep: messages.PickleStep
): messages.TestStep => {
const stepDefinitionIds = registry
.getMatchingStepDefinitions(pickleStep.text)
.map((stepDefinition) => stepDefinition.id);

return {
id: pickleStep.id,
pickleStepId: pickleStep.id,
stepDefinitionIds,
};
};

return {
id: pickleStep.id,
pickleStepId: pickleStep.id,
stepDefinitionIds,
id: pickle.id,
pickleId: pickle.id,
testSteps: [
...beforeHooks.map(hooksToStep),
...pickle.steps.map(pickleStepToTestStep),
...afterHooks.map(hooksToStep),
],
};
};

return {
id: pickle.id,
pickleId: pickle.id,
testSteps: [
...beforeHooks.map(hooksToStep),
...pickle.steps.map(pickleStepToTestStep),
...afterHooks.map(hooksToStep),
],
};
});
});

const specEnvelopes: messages.Envelope[] = [];

Expand Down Expand Up @@ -848,8 +860,6 @@ export default function createTests(
});
}

const testFilter = createTestFilter(gherkinDocument, Cypress.env());

const context: CompositionContext = {
registry,
newId,
Expand Down

0 comments on commit d72224a

Please sign in to comment.