Skip to content

Commit

Permalink
Check for duplicate fixture names, see #52
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalets committed Oct 9, 2023
1 parent c8f2659 commit 08c8b72
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Changelog

## dev
* i18n: Generate scenario outlines correctly [#60](https://github.com/vitalets/playwright-bdd/issues/60)).
* i18n: Generate scenario outlines correctly [#60](https://github.com/vitalets/playwright-bdd/issues/60).
* Check for duplicate fixture names [#52](https://github.com/vitalets/playwright-bdd/issues/52)

## 5.3.0
* Add support for Playwright `1.38`.
Expand Down
23 changes: 20 additions & 3 deletions src/stepDefinitions/decorators/poms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { TestType } from '@playwright/test';
import { BuiltInFixtures } from '../../playwright/types';
import { BddFixtures } from '../../run/bddFixtures';
import { linkStepsWithPomNode } from './steps';
import { exitWithMessage } from '../../utils';

type PomClass = Function;

Expand All @@ -17,9 +18,10 @@ type PomClass = Function;
*/
const pomGraph = new Map<PomClass, PomNode>();

// Representation of POM class with inherited children classes.
// POM class with inherited children POMs: representation of classes inheritance.
export type PomNode = {
fixtureName: string;
className: string;
children: Set<PomNode>;
};

Expand All @@ -38,17 +40,32 @@ export function Fixture<T>(fixtureName: CustomFixturesNames<T>) {
}

function createPomNode(Ctor: PomClass, fixtureName: string) {
const pomNode: PomNode = { fixtureName, children: new Set() };
const pomNode: PomNode = {
fixtureName,
className: Ctor.name,
children: new Set(),
};
ensureUniqueFixtureName(pomNode);
pomGraph.set(Ctor, pomNode);
linkStepsWithPomNode(Ctor, pomNode);
linkParentWithPomNode(Ctor, pomNode);
return pomNode;
}

function ensureUniqueFixtureName({ fixtureName, className }: PomNode) {
if (!fixtureName) return;
const existingPom = getPomNodeByFixtureName(fixtureName);
if (existingPom)
exitWithMessage(
`Duplicate fixture name "${fixtureName}"`,
`defined for classes: ${existingPom.className}, ${className}`,
);
}

function linkParentWithPomNode(Ctor: PomClass, pomNode: PomNode) {
const parentCtor = Object.getPrototypeOf(Ctor);
if (!parentCtor) return;
// if parentCtor is not in pomGraph, add it as well
// if parentCtor is not in pomGraph, add it.
// Case: parent class is not marked with @Fixture, but has decorator steps (base class)
const parentPomNode = pomGraph.get(parentCtor) || createPomNode(parentCtor, '');
parentPomNode.children.add(pomNode);
Expand Down
25 changes: 25 additions & 0 deletions test/decorators-duplicate-fixture-name/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { test as base } from '../../dist';
import { Fixture, Given } from '../../dist/decorators';

type Fixtures = {
todoPage: TodoPage;
todoPage2: TodoPage2;
};

export const test = base.extend<Fixtures>({
todoPage: ({}, use) => use(new TodoPage()),
todoPage2: ({}, use) => use(new TodoPage2()),
});

@Fixture<typeof test>('todoPage')
class TodoPage {
@Given('TodoPage: step')
async step() {}
}

// notice the same fixture name
@Fixture<typeof test>('todoPage')
class TodoPage2 {
@Given('TodoPage2: step')
async step() {}
}
12 changes: 12 additions & 0 deletions test/decorators-duplicate-fixture-name/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from '../../dist';

const testDir = defineBddConfig({
importTestFrom: 'fixtures.ts',
paths: [`sample.feature`],
});

export default defineConfig({
testDir,
forbidOnly: Boolean(process.env.FORBID_ONLY),
});
4 changes: 4 additions & 0 deletions test/decorators-duplicate-fixture-name/sample.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Feature: duplicate fixture name

Scenario: sample scenario
Given TodoPage: step
9 changes: 9 additions & 0 deletions test/decorators-duplicate-fixture-name/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { test, TestDir, execPlaywrightTestWithError } from '../helpers.mjs';

const testDir = new TestDir(import.meta);

test(testDir.name, () =>
execPlaywrightTestWithError(testDir.name, [
`Duplicate fixture name "todoPage" defined for classes: TodoPage, TodoPage2`,
]),
);

0 comments on commit 08c8b72

Please sign in to comment.