@bernierllc/content-management-tests 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +33 -127
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -136
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -30
package/dist/index.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
5
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
10
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
-
};
|
|
12
7
|
var __export = (target, all) => {
|
|
13
8
|
for (var name in all)
|
|
14
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -21,56 +16,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
16
|
}
|
|
22
17
|
return to;
|
|
23
18
|
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
-
mod
|
|
31
|
-
));
|
|
32
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
20
|
|
|
34
|
-
// jest.config.js
|
|
35
|
-
var require_jest_config = __commonJS({
|
|
36
|
-
"jest.config.js"(exports2, module2) {
|
|
37
|
-
"use strict";
|
|
38
|
-
module2.exports = {
|
|
39
|
-
testEnvironment: "jsdom",
|
|
40
|
-
setupFilesAfterEnv: ["<rootDir>/src/setup/jest.setup.ts"],
|
|
41
|
-
testMatch: [
|
|
42
|
-
"<rootDir>/src/**/*.test.ts",
|
|
43
|
-
"<rootDir>/src/**/*.test.tsx"
|
|
44
|
-
],
|
|
45
|
-
collectCoverageFrom: [
|
|
46
|
-
"src/**/*.{ts,tsx}",
|
|
47
|
-
"!src/**/*.test.{ts,tsx}",
|
|
48
|
-
"!src/**/*.stories.{ts,tsx}",
|
|
49
|
-
"!src/setup/**",
|
|
50
|
-
"!src/fixtures/**",
|
|
51
|
-
"!src/mocks/**"
|
|
52
|
-
],
|
|
53
|
-
coverageThreshold: {
|
|
54
|
-
global: {
|
|
55
|
-
branches: 80,
|
|
56
|
-
functions: 80,
|
|
57
|
-
lines: 80,
|
|
58
|
-
statements: 80
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
moduleNameMapper: {
|
|
62
|
-
"^@/(.*)$": "<rootDir>/src/$1",
|
|
63
|
-
"^@test/(.*)$": "<rootDir>/src/test-utils/$1",
|
|
64
|
-
"^@fixtures/(.*)$": "<rootDir>/src/fixtures/$1",
|
|
65
|
-
"^@mocks/(.*)$": "<rootDir>/src/mocks/$1"
|
|
66
|
-
},
|
|
67
|
-
transform: {
|
|
68
|
-
"^.+\\.(ts|tsx)$": "ts-jest"
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
21
|
// src/index.ts
|
|
75
22
|
var src_exports = {};
|
|
76
23
|
__export(src_exports, {
|
|
@@ -86,13 +33,11 @@ __export(src_exports, {
|
|
|
86
33
|
createTestUtils: () => createTestUtils,
|
|
87
34
|
dateFixtures: () => dateFixtures,
|
|
88
35
|
defaultTestConfig: () => defaultTestConfig,
|
|
89
|
-
expect: () =>
|
|
36
|
+
expect: () => import_test2.expect,
|
|
90
37
|
fireEvent: () => import_react2.fireEvent,
|
|
91
|
-
jestConfig: () => import_jest.default,
|
|
92
|
-
playwrightConfig: () => playwright_config_default,
|
|
93
38
|
render: () => import_react2.render,
|
|
94
39
|
screen: () => import_react2.screen,
|
|
95
|
-
test: () =>
|
|
40
|
+
test: () => import_test2.test,
|
|
96
41
|
testDataGenerators: () => testDataGenerators,
|
|
97
42
|
userEvent: () => import_user_event.userEvent,
|
|
98
43
|
userFixtures: () => userFixtures,
|
|
@@ -735,13 +680,19 @@ var import_util = require("util");
|
|
|
735
680
|
global.TextEncoder = import_util.TextEncoder;
|
|
736
681
|
global.TextDecoder = import_util.TextDecoder;
|
|
737
682
|
global.IntersectionObserver = class IntersectionObserver {
|
|
738
|
-
constructor() {
|
|
683
|
+
constructor(_callback, _options) {
|
|
684
|
+
this.root = null;
|
|
685
|
+
this.rootMargin = "";
|
|
686
|
+
this.thresholds = [];
|
|
739
687
|
}
|
|
740
688
|
disconnect() {
|
|
741
689
|
}
|
|
742
|
-
observe() {
|
|
690
|
+
observe(_target) {
|
|
743
691
|
}
|
|
744
|
-
unobserve() {
|
|
692
|
+
unobserve(_target) {
|
|
693
|
+
}
|
|
694
|
+
takeRecords() {
|
|
695
|
+
return [];
|
|
745
696
|
}
|
|
746
697
|
};
|
|
747
698
|
global.ResizeObserver = class ResizeObserver {
|
|
@@ -769,20 +720,29 @@ Object.defineProperty(window, "matchMedia", {
|
|
|
769
720
|
dispatchEvent: jest.fn()
|
|
770
721
|
}))
|
|
771
722
|
});
|
|
772
|
-
var
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
723
|
+
var createStorageMock = () => {
|
|
724
|
+
const store = {};
|
|
725
|
+
return {
|
|
726
|
+
getItem: jest.fn((key) => store[key] ?? null),
|
|
727
|
+
setItem: jest.fn((key, value) => {
|
|
728
|
+
store[key] = value;
|
|
729
|
+
}),
|
|
730
|
+
removeItem: jest.fn((key) => {
|
|
731
|
+
delete store[key];
|
|
732
|
+
}),
|
|
733
|
+
clear: jest.fn(() => {
|
|
734
|
+
Object.keys(store).forEach((key) => delete store[key]);
|
|
735
|
+
}),
|
|
736
|
+
get length() {
|
|
737
|
+
return Object.keys(store).length;
|
|
738
|
+
},
|
|
739
|
+
key: jest.fn((index) => Object.keys(store)[index] ?? null)
|
|
740
|
+
};
|
|
784
741
|
};
|
|
785
|
-
|
|
742
|
+
var localStorageMock = createStorageMock();
|
|
743
|
+
Object.defineProperty(global, "localStorage", { value: localStorageMock, writable: true });
|
|
744
|
+
var sessionStorageMock = createStorageMock();
|
|
745
|
+
Object.defineProperty(global, "sessionStorage", { value: sessionStorageMock, writable: true });
|
|
786
746
|
global.fetch = jest.fn();
|
|
787
747
|
var originalError = console.error;
|
|
788
748
|
var originalWarn = console.warn;
|
|
@@ -813,59 +773,7 @@ afterEach(() => {
|
|
|
813
773
|
// src/index.ts
|
|
814
774
|
var import_react2 = require("@testing-library/react");
|
|
815
775
|
var import_user_event = require("@testing-library/user-event");
|
|
816
|
-
var import_test3 = require("@playwright/test");
|
|
817
|
-
|
|
818
|
-
// playwright.config.ts
|
|
819
776
|
var import_test2 = require("@playwright/test");
|
|
820
|
-
var playwright_config_default = (0, import_test2.defineConfig)({
|
|
821
|
-
testDir: "./src/playwright",
|
|
822
|
-
fullyParallel: true,
|
|
823
|
-
forbidOnly: !!process.env.CI,
|
|
824
|
-
retries: process.env.CI ? 2 : 0,
|
|
825
|
-
workers: process.env.CI ? 1 : void 0,
|
|
826
|
-
reporter: [
|
|
827
|
-
["html"],
|
|
828
|
-
["json", { outputFile: "test-results/results.json" }],
|
|
829
|
-
["junit", { outputFile: "test-results/results.xml" }]
|
|
830
|
-
],
|
|
831
|
-
use: {
|
|
832
|
-
baseURL: "http://localhost:3000",
|
|
833
|
-
trace: "on-first-retry",
|
|
834
|
-
screenshot: "only-on-failure",
|
|
835
|
-
video: "retain-on-failure"
|
|
836
|
-
},
|
|
837
|
-
projects: [
|
|
838
|
-
{
|
|
839
|
-
name: "chromium",
|
|
840
|
-
use: { ...import_test2.devices["Desktop Chrome"] }
|
|
841
|
-
},
|
|
842
|
-
{
|
|
843
|
-
name: "firefox",
|
|
844
|
-
use: { ...import_test2.devices["Desktop Firefox"] }
|
|
845
|
-
},
|
|
846
|
-
{
|
|
847
|
-
name: "webkit",
|
|
848
|
-
use: { ...import_test2.devices["Desktop Safari"] }
|
|
849
|
-
},
|
|
850
|
-
{
|
|
851
|
-
name: "Mobile Chrome",
|
|
852
|
-
use: { ...import_test2.devices["Pixel 5"] }
|
|
853
|
-
},
|
|
854
|
-
{
|
|
855
|
-
name: "Mobile Safari",
|
|
856
|
-
use: { ...import_test2.devices["iPhone 12"] }
|
|
857
|
-
}
|
|
858
|
-
],
|
|
859
|
-
webServer: {
|
|
860
|
-
command: "npm run start:test",
|
|
861
|
-
url: "http://localhost:3000",
|
|
862
|
-
reuseExistingServer: !process.env.CI,
|
|
863
|
-
timeout: 120 * 1e3
|
|
864
|
-
}
|
|
865
|
-
});
|
|
866
|
-
|
|
867
|
-
// src/index.ts
|
|
868
|
-
var import_jest = __toESM(require_jest_config());
|
|
869
777
|
var TestRunner = class {
|
|
870
778
|
constructor(config) {
|
|
871
779
|
this.suites = [];
|
|
@@ -1090,8 +998,6 @@ var defaultTestConfig = {
|
|
|
1090
998
|
defaultTestConfig,
|
|
1091
999
|
expect,
|
|
1092
1000
|
fireEvent,
|
|
1093
|
-
jestConfig,
|
|
1094
|
-
playwrightConfig,
|
|
1095
1001
|
render,
|
|
1096
1002
|
screen,
|
|
1097
1003
|
test,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../jest.config.js","../src/index.ts","../src/test-utils/test-utils.ts","../src/fixtures/index.ts","../src/setup/jest.setup.ts","../playwright.config.ts"],"sourcesContent":["module.exports = {\n testEnvironment: 'jsdom',\n setupFilesAfterEnv: ['<rootDir>/src/setup/jest.setup.ts'],\n testMatch: [\n '<rootDir>/src/**/*.test.ts',\n '<rootDir>/src/**/*.test.tsx'\n ],\n collectCoverageFrom: [\n 'src/**/*.{ts,tsx}',\n '!src/**/*.test.{ts,tsx}',\n '!src/**/*.stories.{ts,tsx}',\n '!src/setup/**',\n '!src/fixtures/**',\n '!src/mocks/**'\n ],\n coverageThreshold: {\n global: {\n branches: 80,\n functions: 80,\n lines: 80,\n statements: 80\n }\n },\n moduleNameMapper: {\n '^@/(.*)$': '<rootDir>/src/$1',\n '^@test/(.*)$': '<rootDir>/src/test-utils/$1',\n '^@fixtures/(.*)$': '<rootDir>/src/fixtures/$1',\n '^@mocks/(.*)$': '<rootDir>/src/mocks/$1'\n },\n transform: {\n '^.+\\\\.(ts|tsx)$': 'ts-jest'\n },\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\n// Test utilities\nexport * from './test-utils/test-utils';\n\n// Test fixtures\nexport * from './fixtures';\n\n// Test setup\nexport * from './setup/jest.setup';\n\n// Re-export testing libraries for convenience\nexport { render, screen, fireEvent, waitFor } from '@testing-library/react';\nexport { userEvent } from '@testing-library/user-event';\nexport { test, expect } from '@playwright/test';\n\n// Test configuration\nexport { default as playwrightConfig } from '../playwright.config';\nexport { default as jestConfig } from '../jest.config';\n\n// Test types\nexport interface TestConfig {\n baseURL: string;\n timeout: number;\n retries: number;\n workers: number;\n reporter: string[];\n browser: string[];\n mobile: boolean;\n tablet: boolean;\n desktop: boolean;\n}\n\nexport interface TestSuite {\n name: string;\n description: string;\n tests: TestCase[];\n setup?: () => Promise<void>;\n teardown?: () => Promise<void>;\n}\n\nexport interface TestCase {\n name: string;\n description: string;\n test: () => Promise<void>;\n timeout?: number;\n retries?: number;\n skip?: boolean;\n only?: boolean;\n}\n\nexport interface TestResult {\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: Error;\n screenshots?: string[];\n video?: string;\n trace?: string;\n}\n\nexport interface TestReport {\n suite: string;\n results: TestResult[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n };\n}\n\n// Test runner utilities\nexport class TestRunner {\n private config: TestConfig;\n private suites: TestSuite[] = [];\n\n constructor(config: TestConfig) {\n this.config = config;\n }\n\n addSuite(suite: TestSuite): void {\n this.suites.push(suite);\n }\n\n async runSuite(suiteName: string): Promise<TestReport> {\n const suite = this.suites.find(s => s.name === suiteName);\n if (!suite) {\n throw new Error(`Suite ${suiteName} not found`);\n }\n\n const results: TestResult[] = [];\n const startTime = Date.now();\n\n try {\n if (suite.setup) {\n await suite.setup();\n }\n\n for (const testCase of suite.tests) {\n if (testCase.skip) {\n results.push({\n name: testCase.name,\n status: 'skipped',\n duration: 0\n });\n continue;\n }\n\n const testStartTime = Date.now();\n try {\n await testCase.test();\n results.push({\n name: testCase.name,\n status: 'passed',\n duration: Date.now() - testStartTime\n });\n } catch (error) {\n results.push({\n name: testCase.name,\n status: 'failed',\n duration: Date.now() - testStartTime,\n error: error as Error\n });\n }\n }\n } finally {\n if (suite.teardown) {\n await suite.teardown();\n }\n }\n\n const summary = {\n total: results.length,\n passed: results.filter(r => r.status === 'passed').length,\n failed: results.filter(r => r.status === 'failed').length,\n skipped: results.filter(r => r.status === 'skipped').length,\n duration: Date.now() - startTime\n };\n\n return {\n suite: suiteName,\n results,\n summary\n };\n }\n\n async runAllSuites(): Promise<TestReport[]> {\n const reports: TestReport[] = [];\n \n for (const suite of this.suites) {\n const report = await this.runSuite(suite.name);\n reports.push(report);\n }\n\n return reports;\n }\n}\n\n// Test data generators\nexport class TestDataGenerator {\n static generateContent(type: string, overrides: any = {}): any {\n const base = {\n id: `test-${Date.now()}`,\n type,\n title: `Test ${type} Content`,\n slug: `test-${type}-content`,\n body: `Test content for ${type}`,\n author: {\n id: 'test-user',\n name: 'Test User',\n email: 'test@example.com'\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n\n static generateWorkflow(overrides: any = {}): any {\n const base = {\n id: `test-workflow-${Date.now()}`,\n name: 'Test Workflow',\n description: 'Test workflow for testing',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n };\n\n return { ...base, ...overrides };\n }\n\n static generateUser(role: string = 'user', overrides: any = {}): any {\n const base = {\n id: `test-user-${Date.now()}`,\n name: 'Test User',\n email: 'test@example.com',\n role,\n permissions: role === 'admin' ? ['*'] : ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n}\n\n// Test assertions\nexport class TestAssertions {\n static async expectElementVisible(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeVisible();\n }\n\n static async expectElementHidden(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeHidden();\n }\n\n static async expectTextVisible(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeVisible();\n }\n\n static async expectTextHidden(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeHidden();\n }\n\n static async expectElementCount(page: any, selector: string, count: number): Promise<void> {\n const elements = await page.locator(selector);\n await expect(elements).toHaveCount(count);\n }\n\n static async expectElementText(page: any, selector: string, text: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveText(text);\n }\n\n static async expectElementValue(page: any, selector: string, value: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveValue(value);\n }\n}\n\n// Test helpers\nexport class TestHelpers {\n static async waitForElement(page: any, selector: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(selector, { timeout });\n }\n\n static async waitForText(page: any, text: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(`text=${text}`, { timeout });\n }\n\n static async fillForm(page: any, formData: Record<string, string>): Promise<void> {\n for (const [field, value] of Object.entries(formData)) {\n await page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n static async clickButton(page: any, text: string): Promise<void> {\n await page.click(`button:has-text(\"${text}\")`);\n }\n\n static async clickLink(page: any, text: string): Promise<void> {\n await page.click(`a:has-text(\"${text}\")`);\n }\n\n static async takeScreenshot(page: any, name: string): Promise<void> {\n await page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n static async measurePerformance(name: string, fn: () => Promise<void>): Promise<number> {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n}\n\n// Export default configuration\nexport const defaultTestConfig: TestConfig = {\n baseURL: 'http://localhost:3000',\n timeout: 30000,\n retries: 2,\n workers: 1,\n reporter: ['html', 'json'],\n browser: ['chromium', 'firefox', 'webkit'],\n mobile: true,\n tablet: true,\n desktop: true\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { Page, BrowserContext, expect } from '@playwright/test';\n\nexport class TestUtils {\n constructor(\n public page: Page,\n public context: BrowserContext\n ) {}\n\n // Navigation helpers\n async navigateTo(path: string) {\n await this.page.goto(path);\n await this.page.waitForLoadState('networkidle');\n }\n\n async waitForElement(selector: string, timeout = 5000) {\n await this.page.waitForSelector(selector, { timeout });\n }\n\n async waitForText(text: string, timeout = 5000) {\n await this.page.waitForSelector(`text=${text}`, { timeout });\n }\n\n // Form helpers\n async fillForm(formData: Record<string, string>) {\n for (const [field, value] of Object.entries(formData)) {\n await this.page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n async clickButton(text: string) {\n await this.page.click(`button:has-text(\"${text}\")`);\n }\n\n async clickLink(text: string) {\n await this.page.click(`a:has-text(\"${text}\")`);\n }\n\n // Content management helpers\n async createContent(type: string, data: Record<string, any>) {\n await this.navigateTo('/admin/content/new');\n await this.page.selectOption('[name=\"contentType\"]', type);\n \n // Fill content fields\n await this.fillForm(data);\n \n // Save as draft\n await this.clickButton('Save as Draft');\n await this.waitForText('Content saved successfully');\n }\n\n async editContent(contentId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n \n // Fill updated fields\n await this.fillForm(updates);\n \n // Save changes\n await this.clickButton('Save Changes');\n await this.waitForText('Content updated successfully');\n }\n\n async publishContent(contentId: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Publish');\n await this.waitForText('Content published successfully');\n }\n\n async scheduleContent(contentId: string, date: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.page.fill('[name=\"publishDate\"]', date);\n await this.clickButton('Schedule');\n await this.waitForText('Content scheduled successfully');\n }\n\n async deleteContent(contentId: string, soft = true) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Delete');\n \n if (!soft) {\n await this.page.click('[data-testid=\"confirm-delete\"]');\n }\n \n await this.waitForText('Content deleted successfully');\n }\n\n // Workflow helpers\n async createWorkflow(workflowData: Record<string, any>) {\n await this.navigateTo('/admin/workflows/new');\n await this.fillForm(workflowData);\n await this.clickButton('Create Workflow');\n await this.waitForText('Workflow created successfully');\n }\n\n async updateWorkflow(workflowId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Workflow');\n await this.waitForText('Workflow updated successfully');\n }\n\n async deleteWorkflow(workflowId: string) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.clickButton('Delete Workflow');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Workflow deleted successfully');\n }\n\n // Content type helpers\n async createContentType(contentTypeData: Record<string, any>) {\n await this.navigateTo('/admin/content-types/new');\n await this.fillForm(contentTypeData);\n await this.clickButton('Create Content Type');\n await this.waitForText('Content type created successfully');\n }\n\n async updateContentType(contentTypeId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Content Type');\n await this.waitForText('Content type updated successfully');\n }\n\n async deleteContentType(contentTypeId: string) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.clickButton('Delete Content Type');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Content type deleted successfully');\n }\n\n // User helpers\n async createUser(userData: Record<string, any>) {\n await this.navigateTo('/admin/users/new');\n await this.fillForm(userData);\n await this.clickButton('Create User');\n await this.waitForText('User created successfully');\n }\n\n async updateUser(userId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update User');\n await this.waitForText('User updated successfully');\n }\n\n async deleteUser(userId: string) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.clickButton('Delete User');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('User deleted successfully');\n }\n\n // Authentication helpers\n async login(email: string, password: string) {\n await this.navigateTo('/login');\n await this.fillForm({ email, password });\n await this.clickButton('Login');\n await this.waitForText('Welcome');\n }\n\n async logout() {\n await this.clickButton('Logout');\n await this.waitForText('Logged out successfully');\n }\n\n // API helpers\n async apiRequest(method: string, endpoint: string, data?: any) {\n const response = await this.page.request.fetch(`/api${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n data: data ? JSON.stringify(data) : undefined,\n });\n \n return response;\n }\n\n async getContent(contentId: string) {\n const response = await this.apiRequest('GET', `/content/${contentId}`);\n return response.json();\n }\n\n async createContentViaAPI(type: string, data: Record<string, any>) {\n const response = await this.apiRequest('POST', '/content', { type, data });\n return response.json();\n }\n\n async updateContentViaAPI(contentId: string, data: Record<string, any>) {\n const response = await this.apiRequest('PUT', `/content/${contentId}`, { data });\n return response.json();\n }\n\n async deleteContentViaAPI(contentId: string, soft = true) {\n const response = await this.apiRequest('DELETE', `/content/${contentId}?soft=${soft}`);\n return response;\n }\n\n // Assertion helpers\n async expectElementVisible(selector: string) {\n await expect(this.page.locator(selector)).toBeVisible();\n }\n\n async expectElementHidden(selector: string) {\n await expect(this.page.locator(selector)).toBeHidden();\n }\n\n async expectTextVisible(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeVisible();\n }\n\n async expectTextHidden(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeHidden();\n }\n\n async expectElementCount(selector: string, count: number) {\n await expect(this.page.locator(selector)).toHaveCount(count);\n }\n\n async expectElementText(selector: string, text: string) {\n await expect(this.page.locator(selector)).toHaveText(text);\n }\n\n async expectElementValue(selector: string, value: string) {\n await expect(this.page.locator(selector)).toHaveValue(value);\n }\n\n // Screenshot helpers\n async takeScreenshot(name: string) {\n await this.page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n async takeElementScreenshot(selector: string, name: string) {\n await this.page.locator(selector).screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n // Performance helpers\n async measurePerformance(name: string, fn: () => Promise<void>) {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n\n // Accessibility helpers\n async checkAccessibility() {\n // This would integrate with axe-core or similar\n // For now, just check for basic accessibility attributes\n const elements = await this.page.locator('[role]').all();\n expect(elements.length).toBeGreaterThan(0);\n }\n\n // Mobile helpers\n async switchToMobile() {\n await this.page.setViewportSize({ width: 375, height: 667 });\n }\n\n async switchToTablet() {\n await this.page.setViewportSize({ width: 768, height: 1024 });\n }\n\n async switchToDesktop() {\n await this.page.setViewportSize({ width: 1920, height: 1080 });\n }\n\n // Cleanup helpers\n async cleanup() {\n // Clean up any test data\n await this.page.evaluate(() => {\n localStorage.clear();\n sessionStorage.clear();\n });\n }\n}\n\n// Export factory function\nexport function createTestUtils(page: Page, context: BrowserContext) {\n return new TestUtils(page, context);\n}\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { faker } from '@faker-js/faker';\nimport { v4 as uuidv4 } from 'uuid';\nimport { format, addDays, subDays } from 'date-fns';\n\n// Content fixtures\nexport const contentFixtures = {\n text: {\n id: uuidv4(),\n type: 'text',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n body: faker.lorem.paragraphs(3),\n excerpt: faker.lorem.sentence(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['general'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n image: {\n id: uuidv4(),\n type: 'image',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n altText: faker.lorem.sentence(),\n imageUrl: faker.image.url(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['photography'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n audio: {\n id: uuidv4(),\n type: 'audio',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n audioUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n metadata: {\n artist: faker.person.fullName(),\n album: faker.lorem.words(2),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['podcast'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n video: {\n id: uuidv4(),\n type: 'video',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n videoUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n dimensions: {\n width: 1920,\n height: 1080\n },\n metadata: {\n director: faker.person.fullName(),\n genre: faker.lorem.word(),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['tutorial'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n }\n};\n\n// Workflow fixtures\nexport const workflowFixtures = {\n simple: {\n id: 'simple',\n name: 'Simple Workflow',\n description: 'A simple two-stage workflow',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n },\n\n editorial: {\n id: 'editorial',\n name: 'Editorial Workflow',\n description: 'A comprehensive editorial workflow',\n stages: [\n {\n id: 'write',\n name: 'Write',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'edit',\n name: 'Edit',\n order: 2,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'review',\n name: 'Review',\n order: 3,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.review']\n },\n {\n id: 'publish',\n name: 'Publish',\n order: 4,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'write-to-edit',\n from: 'write',\n to: 'edit',\n permissions: ['content.edit']\n },\n {\n id: 'edit-to-review',\n from: 'edit',\n to: 'review',\n permissions: ['content.review']\n },\n {\n id: 'review-to-publish',\n from: 'review',\n to: 'publish',\n permissions: ['content.publish']\n }\n ]\n }\n};\n\n// User fixtures\nexport const userFixtures = {\n admin: {\n id: uuidv4(),\n name: 'Admin User',\n email: 'admin@example.com',\n role: 'admin',\n permissions: ['*'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n editor: {\n id: uuidv4(),\n name: 'Editor User',\n email: 'editor@example.com',\n role: 'editor',\n permissions: ['content.edit', 'content.publish', 'content.schedule'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n author: {\n id: uuidv4(),\n name: 'Author User',\n email: 'author@example.com',\n role: 'author',\n permissions: ['content.edit'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n user: {\n id: uuidv4(),\n name: 'Regular User',\n email: 'user@example.com',\n role: 'user',\n permissions: ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n }\n};\n\n// Content type fixtures\nexport const contentTypeFixtures = {\n text: {\n id: 'text',\n name: 'Text Content',\n description: 'Rich text content with formatting',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n body: { type: 'string', required: true },\n excerpt: { type: 'string', required: false },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'TextEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'body', type: 'textarea', label: 'Body', required: true },\n { name: 'excerpt', type: 'textarea', label: 'Excerpt', required: false },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n },\n\n image: {\n id: 'image',\n name: 'Image Content',\n description: 'Image content with metadata',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n description: { type: 'string', required: false },\n altText: { type: 'string', required: true },\n imageUrl: { type: 'string', required: true },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'ImageEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'description', type: 'textarea', label: 'Description', required: false },\n { name: 'altText', type: 'text', label: 'Alt Text', required: true },\n { name: 'imageUrl', type: 'url', label: 'Image URL', required: true },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n }\n};\n\n// Configuration fixtures\nexport const configFixtures = {\n development: {\n server: {\n port: 3000,\n host: 'localhost',\n cors: {\n origin: '*',\n credentials: true\n }\n },\n database: {\n type: 'sqlite',\n name: 'content_management_dev'\n },\n logging: {\n level: 'debug',\n format: 'text',\n console: {\n enabled: true,\n colorize: true\n }\n }\n },\n\n production: {\n server: {\n port: 80,\n host: '0.0.0.0',\n cors: {\n origin: ['https://myapp.com'],\n credentials: true\n }\n },\n database: {\n type: 'postgresql',\n url: 'postgresql://user:password@localhost:5432/content_management'\n },\n logging: {\n level: 'info',\n format: 'json',\n file: {\n enabled: true,\n path: './logs',\n maxSize: '10MB',\n maxFiles: 5\n }\n }\n }\n};\n\n// Test data generators\nexport const testDataGenerators = {\n generateContent: (type: string, overrides: any = {}) => {\n const base = contentFixtures[type as keyof typeof contentFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateWorkflow: (overrides: any = {}) => {\n return {\n ...workflowFixtures.simple,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateUser: (role: string = 'user', overrides: any = {}) => {\n const base = userFixtures[role as keyof typeof userFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateContentType: (overrides: any = {}) => {\n return {\n ...contentTypeFixtures.text,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateConfig: (environment: string = 'development', overrides: any = {}) => {\n const base = configFixtures[environment as keyof typeof configFixtures];\n return {\n ...base,\n ...overrides\n };\n }\n};\n\n// Date fixtures\nexport const dateFixtures = {\n now: new Date(),\n tomorrow: addDays(new Date(), 1),\n yesterday: subDays(new Date(), 1),\n nextWeek: addDays(new Date(), 7),\n lastWeek: subDays(new Date(), 7),\n nextMonth: addDays(new Date(), 30),\n lastMonth: subDays(new Date(), 30)\n};\n\n// API response fixtures\nexport const apiResponseFixtures = {\n success: {\n success: true,\n message: 'Operation completed successfully',\n data: null\n },\n\n error: {\n success: false,\n message: 'An error occurred',\n error: {\n code: 'INTERNAL_ERROR',\n details: 'Something went wrong'\n }\n },\n\n validationError: {\n success: false,\n message: 'Validation failed',\n error: {\n code: 'VALIDATION_ERROR',\n details: {\n field: 'title',\n message: 'Title is required'\n }\n }\n }\n};\n\n// Export all fixtures\nexport default {\n content: contentFixtures,\n workflow: workflowFixtures,\n user: userFixtures,\n contentType: contentTypeFixtures,\n config: configFixtures,\n date: dateFixtures,\n apiResponse: apiResponseFixtures,\n generators: testDataGenerators\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport '@testing-library/jest-dom';\nimport { configure } from '@testing-library/react';\nimport { TextEncoder, TextDecoder } from 'util';\n\n// Configure testing library\nconfigure({ testIdAttribute: 'data-testid' });\n\n// Polyfills for Node.js environment\nglobal.TextEncoder = TextEncoder;\nglobal.TextDecoder = TextDecoder as any;\n\n// Mock IntersectionObserver\nglobal.IntersectionObserver = class IntersectionObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock ResizeObserver\nglobal.ResizeObserver = class ResizeObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock matchMedia\nObject.defineProperty(window, 'matchMedia', {\n writable: true,\n value: jest.fn().mockImplementation(query => ({\n matches: false,\n media: query,\n onchange: null,\n addListener: jest.fn(), // deprecated\n removeListener: jest.fn(), // deprecated\n addEventListener: jest.fn(),\n removeEventListener: jest.fn(),\n dispatchEvent: jest.fn(),\n })),\n});\n\n// Mock localStorage\nconst localStorageMock = {\n getItem: jest.fn(),\n setItem: jest.fn(),\n removeItem: jest.fn(),\n clear: jest.fn(),\n};\nglobal.localStorage = localStorageMock;\n\n// Mock sessionStorage\nconst sessionStorageMock = {\n getItem: jest.fn(),\n setItem: jest.fn(),\n removeItem: jest.fn(),\n clear: jest.fn(),\n};\nglobal.sessionStorage = sessionStorageMock;\n\n// Mock fetch\nglobal.fetch = jest.fn();\n\n// Mock console methods to reduce noise in tests\nconst originalError = console.error;\nconst originalWarn = console.warn;\n\nbeforeAll(() => {\n console.error = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalError.call(console, ...args);\n };\n\n console.warn = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalWarn.call(console, ...args);\n };\n});\n\nafterAll(() => {\n console.error = originalError;\n console.warn = originalWarn;\n});\n\n// Clean up after each test\nafterEach(() => {\n jest.clearAllMocks();\n localStorageMock.clear();\n sessionStorageMock.clear();\n});\n","import { defineConfig, devices } from '@playwright/test';\n\nexport default defineConfig({\n testDir: './src/playwright',\n fullyParallel: true,\n forbidOnly: !!process.env.CI,\n retries: process.env.CI ? 2 : 0,\n workers: process.env.CI ? 1 : undefined,\n reporter: [\n ['html'],\n ['json', { outputFile: 'test-results/results.json' }],\n ['junit', { outputFile: 'test-results/results.xml' }]\n ],\n use: {\n baseURL: 'http://localhost:3000',\n trace: 'on-first-retry',\n screenshot: 'only-on-failure',\n video: 'retain-on-failure'\n },\n projects: [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] }\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] }\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] }\n },\n {\n name: 'Mobile Chrome',\n use: { ...devices['Pixel 5'] }\n },\n {\n name: 'Mobile Safari',\n use: { ...devices['iPhone 12'] }\n }\n ],\n webServer: {\n command: 'npm run start:test',\n url: 'http://localhost:3000',\n reuseExistingServer: !process.env.CI,\n timeout: 120 * 1000\n }\n});\n"],"mappings":"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","names":["exports","module","uuidv4","import_react","import_test","import_test"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/test-utils/test-utils.ts","../src/fixtures/index.ts","../src/setup/jest.setup.ts"],"sourcesContent":["/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\n// Test utilities\nexport * from './test-utils/test-utils';\n\n// Test fixtures\nexport * from './fixtures';\n\n// Test setup\nexport * from './setup/jest.setup';\n\n// Re-export testing libraries for convenience\nexport { render, screen, fireEvent, waitFor } from '@testing-library/react';\nexport { userEvent } from '@testing-library/user-event';\nexport { test, expect } from '@playwright/test';\n\n// Note: Test configuration files (playwright.config, jest.config) are not exported\n// as they exist outside the src directory. Import them directly if needed.\n\n// Test types\nexport interface TestConfig {\n baseURL: string;\n timeout: number;\n retries: number;\n workers: number;\n reporter: string[];\n browser: string[];\n mobile: boolean;\n tablet: boolean;\n desktop: boolean;\n}\n\nexport interface TestSuite {\n name: string;\n description: string;\n tests: TestCase[];\n setup?: () => Promise<void>;\n teardown?: () => Promise<void>;\n}\n\nexport interface TestCase {\n name: string;\n description: string;\n test: () => Promise<void>;\n timeout?: number;\n retries?: number;\n skip?: boolean;\n only?: boolean;\n}\n\nexport interface TestResult {\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: Error;\n screenshots?: string[];\n video?: string;\n trace?: string;\n}\n\nexport interface TestReport {\n suite: string;\n results: TestResult[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n };\n}\n\n// Test runner utilities\nexport class TestRunner {\n private config: TestConfig;\n private suites: TestSuite[] = [];\n\n constructor(config: TestConfig) {\n this.config = config;\n }\n\n addSuite(suite: TestSuite): void {\n this.suites.push(suite);\n }\n\n async runSuite(suiteName: string): Promise<TestReport> {\n const suite = this.suites.find(s => s.name === suiteName);\n if (!suite) {\n throw new Error(`Suite ${suiteName} not found`);\n }\n\n const results: TestResult[] = [];\n const startTime = Date.now();\n\n try {\n if (suite.setup) {\n await suite.setup();\n }\n\n for (const testCase of suite.tests) {\n if (testCase.skip) {\n results.push({\n name: testCase.name,\n status: 'skipped',\n duration: 0\n });\n continue;\n }\n\n const testStartTime = Date.now();\n try {\n await testCase.test();\n results.push({\n name: testCase.name,\n status: 'passed',\n duration: Date.now() - testStartTime\n });\n } catch (error) {\n results.push({\n name: testCase.name,\n status: 'failed',\n duration: Date.now() - testStartTime,\n error: error as Error\n });\n }\n }\n } finally {\n if (suite.teardown) {\n await suite.teardown();\n }\n }\n\n const summary = {\n total: results.length,\n passed: results.filter(r => r.status === 'passed').length,\n failed: results.filter(r => r.status === 'failed').length,\n skipped: results.filter(r => r.status === 'skipped').length,\n duration: Date.now() - startTime\n };\n\n return {\n suite: suiteName,\n results,\n summary\n };\n }\n\n async runAllSuites(): Promise<TestReport[]> {\n const reports: TestReport[] = [];\n \n for (const suite of this.suites) {\n const report = await this.runSuite(suite.name);\n reports.push(report);\n }\n\n return reports;\n }\n}\n\n// Test data generators\nexport class TestDataGenerator {\n static generateContent(type: string, overrides: any = {}): any {\n const base = {\n id: `test-${Date.now()}`,\n type,\n title: `Test ${type} Content`,\n slug: `test-${type}-content`,\n body: `Test content for ${type}`,\n author: {\n id: 'test-user',\n name: 'Test User',\n email: 'test@example.com'\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n\n static generateWorkflow(overrides: any = {}): any {\n const base = {\n id: `test-workflow-${Date.now()}`,\n name: 'Test Workflow',\n description: 'Test workflow for testing',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n };\n\n return { ...base, ...overrides };\n }\n\n static generateUser(role: string = 'user', overrides: any = {}): any {\n const base = {\n id: `test-user-${Date.now()}`,\n name: 'Test User',\n email: 'test@example.com',\n role,\n permissions: role === 'admin' ? ['*'] : ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n}\n\n// Test assertions\nexport class TestAssertions {\n static async expectElementVisible(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeVisible();\n }\n\n static async expectElementHidden(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeHidden();\n }\n\n static async expectTextVisible(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeVisible();\n }\n\n static async expectTextHidden(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeHidden();\n }\n\n static async expectElementCount(page: any, selector: string, count: number): Promise<void> {\n const elements = await page.locator(selector);\n await expect(elements).toHaveCount(count);\n }\n\n static async expectElementText(page: any, selector: string, text: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveText(text);\n }\n\n static async expectElementValue(page: any, selector: string, value: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveValue(value);\n }\n}\n\n// Test helpers\nexport class TestHelpers {\n static async waitForElement(page: any, selector: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(selector, { timeout });\n }\n\n static async waitForText(page: any, text: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(`text=${text}`, { timeout });\n }\n\n static async fillForm(page: any, formData: Record<string, string>): Promise<void> {\n for (const [field, value] of Object.entries(formData)) {\n await page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n static async clickButton(page: any, text: string): Promise<void> {\n await page.click(`button:has-text(\"${text}\")`);\n }\n\n static async clickLink(page: any, text: string): Promise<void> {\n await page.click(`a:has-text(\"${text}\")`);\n }\n\n static async takeScreenshot(page: any, name: string): Promise<void> {\n await page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n static async measurePerformance(name: string, fn: () => Promise<void>): Promise<number> {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n}\n\n// Export default configuration\nexport const defaultTestConfig: TestConfig = {\n baseURL: 'http://localhost:3000',\n timeout: 30000,\n retries: 2,\n workers: 1,\n reporter: ['html', 'json'],\n browser: ['chromium', 'firefox', 'webkit'],\n mobile: true,\n tablet: true,\n desktop: true\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { Page, BrowserContext, expect } from '@playwright/test';\n\nexport class TestUtils {\n constructor(\n public page: Page,\n public context: BrowserContext\n ) {}\n\n // Navigation helpers\n async navigateTo(path: string) {\n await this.page.goto(path);\n await this.page.waitForLoadState('networkidle');\n }\n\n async waitForElement(selector: string, timeout = 5000) {\n await this.page.waitForSelector(selector, { timeout });\n }\n\n async waitForText(text: string, timeout = 5000) {\n await this.page.waitForSelector(`text=${text}`, { timeout });\n }\n\n // Form helpers\n async fillForm(formData: Record<string, string>) {\n for (const [field, value] of Object.entries(formData)) {\n await this.page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n async clickButton(text: string) {\n await this.page.click(`button:has-text(\"${text}\")`);\n }\n\n async clickLink(text: string) {\n await this.page.click(`a:has-text(\"${text}\")`);\n }\n\n // Content management helpers\n async createContent(type: string, data: Record<string, any>) {\n await this.navigateTo('/admin/content/new');\n await this.page.selectOption('[name=\"contentType\"]', type);\n \n // Fill content fields\n await this.fillForm(data);\n \n // Save as draft\n await this.clickButton('Save as Draft');\n await this.waitForText('Content saved successfully');\n }\n\n async editContent(contentId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n \n // Fill updated fields\n await this.fillForm(updates);\n \n // Save changes\n await this.clickButton('Save Changes');\n await this.waitForText('Content updated successfully');\n }\n\n async publishContent(contentId: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Publish');\n await this.waitForText('Content published successfully');\n }\n\n async scheduleContent(contentId: string, date: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.page.fill('[name=\"publishDate\"]', date);\n await this.clickButton('Schedule');\n await this.waitForText('Content scheduled successfully');\n }\n\n async deleteContent(contentId: string, soft = true) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Delete');\n \n if (!soft) {\n await this.page.click('[data-testid=\"confirm-delete\"]');\n }\n \n await this.waitForText('Content deleted successfully');\n }\n\n // Workflow helpers\n async createWorkflow(workflowData: Record<string, any>) {\n await this.navigateTo('/admin/workflows/new');\n await this.fillForm(workflowData);\n await this.clickButton('Create Workflow');\n await this.waitForText('Workflow created successfully');\n }\n\n async updateWorkflow(workflowId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Workflow');\n await this.waitForText('Workflow updated successfully');\n }\n\n async deleteWorkflow(workflowId: string) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.clickButton('Delete Workflow');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Workflow deleted successfully');\n }\n\n // Content type helpers\n async createContentType(contentTypeData: Record<string, any>) {\n await this.navigateTo('/admin/content-types/new');\n await this.fillForm(contentTypeData);\n await this.clickButton('Create Content Type');\n await this.waitForText('Content type created successfully');\n }\n\n async updateContentType(contentTypeId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Content Type');\n await this.waitForText('Content type updated successfully');\n }\n\n async deleteContentType(contentTypeId: string) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.clickButton('Delete Content Type');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Content type deleted successfully');\n }\n\n // User helpers\n async createUser(userData: Record<string, any>) {\n await this.navigateTo('/admin/users/new');\n await this.fillForm(userData);\n await this.clickButton('Create User');\n await this.waitForText('User created successfully');\n }\n\n async updateUser(userId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update User');\n await this.waitForText('User updated successfully');\n }\n\n async deleteUser(userId: string) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.clickButton('Delete User');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('User deleted successfully');\n }\n\n // Authentication helpers\n async login(email: string, password: string) {\n await this.navigateTo('/login');\n await this.fillForm({ email, password });\n await this.clickButton('Login');\n await this.waitForText('Welcome');\n }\n\n async logout() {\n await this.clickButton('Logout');\n await this.waitForText('Logged out successfully');\n }\n\n // API helpers\n async apiRequest(method: string, endpoint: string, data?: any) {\n const response = await this.page.request.fetch(`/api${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n data: data ? JSON.stringify(data) : undefined,\n });\n \n return response;\n }\n\n async getContent(contentId: string) {\n const response = await this.apiRequest('GET', `/content/${contentId}`);\n return response.json();\n }\n\n async createContentViaAPI(type: string, data: Record<string, any>) {\n const response = await this.apiRequest('POST', '/content', { type, data });\n return response.json();\n }\n\n async updateContentViaAPI(contentId: string, data: Record<string, any>) {\n const response = await this.apiRequest('PUT', `/content/${contentId}`, { data });\n return response.json();\n }\n\n async deleteContentViaAPI(contentId: string, soft = true) {\n const response = await this.apiRequest('DELETE', `/content/${contentId}?soft=${soft}`);\n return response;\n }\n\n // Assertion helpers\n async expectElementVisible(selector: string) {\n await expect(this.page.locator(selector)).toBeVisible();\n }\n\n async expectElementHidden(selector: string) {\n await expect(this.page.locator(selector)).toBeHidden();\n }\n\n async expectTextVisible(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeVisible();\n }\n\n async expectTextHidden(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeHidden();\n }\n\n async expectElementCount(selector: string, count: number) {\n await expect(this.page.locator(selector)).toHaveCount(count);\n }\n\n async expectElementText(selector: string, text: string) {\n await expect(this.page.locator(selector)).toHaveText(text);\n }\n\n async expectElementValue(selector: string, value: string) {\n await expect(this.page.locator(selector)).toHaveValue(value);\n }\n\n // Screenshot helpers\n async takeScreenshot(name: string) {\n await this.page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n async takeElementScreenshot(selector: string, name: string) {\n await this.page.locator(selector).screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n // Performance helpers\n async measurePerformance(name: string, fn: () => Promise<void>) {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n\n // Accessibility helpers\n async checkAccessibility() {\n // This would integrate with axe-core or similar\n // For now, just check for basic accessibility attributes\n const elements = await this.page.locator('[role]').all();\n expect(elements.length).toBeGreaterThan(0);\n }\n\n // Mobile helpers\n async switchToMobile() {\n await this.page.setViewportSize({ width: 375, height: 667 });\n }\n\n async switchToTablet() {\n await this.page.setViewportSize({ width: 768, height: 1024 });\n }\n\n async switchToDesktop() {\n await this.page.setViewportSize({ width: 1920, height: 1080 });\n }\n\n // Cleanup helpers\n async cleanup() {\n // Clean up any test data\n await this.page.evaluate(() => {\n localStorage.clear();\n sessionStorage.clear();\n });\n }\n}\n\n// Export factory function\nexport function createTestUtils(page: Page, context: BrowserContext) {\n return new TestUtils(page, context);\n}\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { faker } from '@faker-js/faker';\nimport { v4 as uuidv4 } from 'uuid';\nimport { format, addDays, subDays } from 'date-fns';\n\n// Content fixtures\nexport const contentFixtures = {\n text: {\n id: uuidv4(),\n type: 'text',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n body: faker.lorem.paragraphs(3),\n excerpt: faker.lorem.sentence(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['general'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n image: {\n id: uuidv4(),\n type: 'image',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n altText: faker.lorem.sentence(),\n imageUrl: faker.image.url(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['photography'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n audio: {\n id: uuidv4(),\n type: 'audio',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n audioUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n metadata: {\n artist: faker.person.fullName(),\n album: faker.lorem.words(2),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['podcast'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n video: {\n id: uuidv4(),\n type: 'video',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n videoUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n dimensions: {\n width: 1920,\n height: 1080\n },\n metadata: {\n director: faker.person.fullName(),\n genre: faker.lorem.word(),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['tutorial'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n }\n};\n\n// Workflow fixtures\nexport const workflowFixtures = {\n simple: {\n id: 'simple',\n name: 'Simple Workflow',\n description: 'A simple two-stage workflow',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n },\n\n editorial: {\n id: 'editorial',\n name: 'Editorial Workflow',\n description: 'A comprehensive editorial workflow',\n stages: [\n {\n id: 'write',\n name: 'Write',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'edit',\n name: 'Edit',\n order: 2,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'review',\n name: 'Review',\n order: 3,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.review']\n },\n {\n id: 'publish',\n name: 'Publish',\n order: 4,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'write-to-edit',\n from: 'write',\n to: 'edit',\n permissions: ['content.edit']\n },\n {\n id: 'edit-to-review',\n from: 'edit',\n to: 'review',\n permissions: ['content.review']\n },\n {\n id: 'review-to-publish',\n from: 'review',\n to: 'publish',\n permissions: ['content.publish']\n }\n ]\n }\n};\n\n// User fixtures\nexport const userFixtures = {\n admin: {\n id: uuidv4(),\n name: 'Admin User',\n email: 'admin@example.com',\n role: 'admin',\n permissions: ['*'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n editor: {\n id: uuidv4(),\n name: 'Editor User',\n email: 'editor@example.com',\n role: 'editor',\n permissions: ['content.edit', 'content.publish', 'content.schedule'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n author: {\n id: uuidv4(),\n name: 'Author User',\n email: 'author@example.com',\n role: 'author',\n permissions: ['content.edit'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n user: {\n id: uuidv4(),\n name: 'Regular User',\n email: 'user@example.com',\n role: 'user',\n permissions: ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n }\n};\n\n// Content type fixtures\nexport const contentTypeFixtures = {\n text: {\n id: 'text',\n name: 'Text Content',\n description: 'Rich text content with formatting',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n body: { type: 'string', required: true },\n excerpt: { type: 'string', required: false },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'TextEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'body', type: 'textarea', label: 'Body', required: true },\n { name: 'excerpt', type: 'textarea', label: 'Excerpt', required: false },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n },\n\n image: {\n id: 'image',\n name: 'Image Content',\n description: 'Image content with metadata',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n description: { type: 'string', required: false },\n altText: { type: 'string', required: true },\n imageUrl: { type: 'string', required: true },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'ImageEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'description', type: 'textarea', label: 'Description', required: false },\n { name: 'altText', type: 'text', label: 'Alt Text', required: true },\n { name: 'imageUrl', type: 'url', label: 'Image URL', required: true },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n }\n};\n\n// Configuration fixtures\nexport const configFixtures = {\n development: {\n server: {\n port: 3000,\n host: 'localhost',\n cors: {\n origin: '*',\n credentials: true\n }\n },\n database: {\n type: 'sqlite',\n name: 'content_management_dev'\n },\n logging: {\n level: 'debug',\n format: 'text',\n console: {\n enabled: true,\n colorize: true\n }\n }\n },\n\n production: {\n server: {\n port: 80,\n host: '0.0.0.0',\n cors: {\n origin: ['https://myapp.com'],\n credentials: true\n }\n },\n database: {\n type: 'postgresql',\n url: 'postgresql://user:password@localhost:5432/content_management'\n },\n logging: {\n level: 'info',\n format: 'json',\n file: {\n enabled: true,\n path: './logs',\n maxSize: '10MB',\n maxFiles: 5\n }\n }\n }\n};\n\n// Test data generators\nexport const testDataGenerators = {\n generateContent: (type: string, overrides: any = {}) => {\n const base = contentFixtures[type as keyof typeof contentFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateWorkflow: (overrides: any = {}) => {\n return {\n ...workflowFixtures.simple,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateUser: (role: string = 'user', overrides: any = {}) => {\n const base = userFixtures[role as keyof typeof userFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateContentType: (overrides: any = {}) => {\n return {\n ...contentTypeFixtures.text,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateConfig: (environment: string = 'development', overrides: any = {}) => {\n const base = configFixtures[environment as keyof typeof configFixtures];\n return {\n ...base,\n ...overrides\n };\n }\n};\n\n// Date fixtures\nexport const dateFixtures = {\n now: new Date(),\n tomorrow: addDays(new Date(), 1),\n yesterday: subDays(new Date(), 1),\n nextWeek: addDays(new Date(), 7),\n lastWeek: subDays(new Date(), 7),\n nextMonth: addDays(new Date(), 30),\n lastMonth: subDays(new Date(), 30)\n};\n\n// API response fixtures\nexport const apiResponseFixtures = {\n success: {\n success: true,\n message: 'Operation completed successfully',\n data: null\n },\n\n error: {\n success: false,\n message: 'An error occurred',\n error: {\n code: 'INTERNAL_ERROR',\n details: 'Something went wrong'\n }\n },\n\n validationError: {\n success: false,\n message: 'Validation failed',\n error: {\n code: 'VALIDATION_ERROR',\n details: {\n field: 'title',\n message: 'Title is required'\n }\n }\n }\n};\n\n// Export all fixtures\nexport default {\n content: contentFixtures,\n workflow: workflowFixtures,\n user: userFixtures,\n contentType: contentTypeFixtures,\n config: configFixtures,\n date: dateFixtures,\n apiResponse: apiResponseFixtures,\n generators: testDataGenerators\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport '@testing-library/jest-dom';\nimport { configure } from '@testing-library/react';\nimport { TextEncoder, TextDecoder } from 'util';\n\n// Configure testing library\nconfigure({ testIdAttribute: 'data-testid' });\n\n// Polyfills for Node.js environment\nglobal.TextEncoder = TextEncoder as unknown as typeof globalThis.TextEncoder;\nglobal.TextDecoder = TextDecoder as unknown as typeof globalThis.TextDecoder;\n\n// Mock IntersectionObserver\nglobal.IntersectionObserver = class IntersectionObserver implements globalThis.IntersectionObserver {\n readonly root: Element | Document | null = null;\n readonly rootMargin: string = '';\n readonly thresholds: ReadonlyArray<number> = [];\n constructor(_callback: IntersectionObserverCallback, _options?: IntersectionObserverInit) {}\n disconnect(): void {}\n observe(_target: Element): void {}\n unobserve(_target: Element): void {}\n takeRecords(): IntersectionObserverEntry[] { return []; }\n};\n\n// Mock ResizeObserver\nglobal.ResizeObserver = class ResizeObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock matchMedia\nObject.defineProperty(window, 'matchMedia', {\n writable: true,\n value: jest.fn().mockImplementation(query => ({\n matches: false,\n media: query,\n onchange: null,\n addListener: jest.fn(), // deprecated\n removeListener: jest.fn(), // deprecated\n addEventListener: jest.fn(),\n removeEventListener: jest.fn(),\n dispatchEvent: jest.fn(),\n })),\n});\n\n// Mock localStorage\nconst createStorageMock = (): Storage => {\n const store: Record<string, string> = {};\n return {\n getItem: jest.fn((key: string) => store[key] ?? null),\n setItem: jest.fn((key: string, value: string) => { store[key] = value; }),\n removeItem: jest.fn((key: string) => { delete store[key]; }),\n clear: jest.fn(() => { Object.keys(store).forEach(key => delete store[key]); }),\n get length() { return Object.keys(store).length; },\n key: jest.fn((index: number) => Object.keys(store)[index] ?? null),\n };\n};\nconst localStorageMock = createStorageMock();\nObject.defineProperty(global, 'localStorage', { value: localStorageMock, writable: true });\n\n// Mock sessionStorage\nconst sessionStorageMock = createStorageMock();\nObject.defineProperty(global, 'sessionStorage', { value: sessionStorageMock, writable: true });\n\n// Mock fetch\nglobal.fetch = jest.fn();\n\n// Mock console methods to reduce noise in tests\nconst originalError = console.error;\nconst originalWarn = console.warn;\n\nbeforeAll(() => {\n console.error = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalError.call(console, ...args);\n };\n\n console.warn = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalWarn.call(console, ...args);\n };\n});\n\nafterAll(() => {\n console.error = originalError;\n console.warn = originalWarn;\n});\n\n// Clean up after each test\nafterEach(() => {\n jest.clearAllMocks();\n localStorageMock.clear();\n sessionStorageMock.clear();\n});\n"],"mappings":"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","names":["uuidv4","import_react","import_test"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,69 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
|
|
28
|
-
// jest.config.js
|
|
29
|
-
var require_jest_config = __commonJS({
|
|
30
|
-
"jest.config.js"(exports, module) {
|
|
31
|
-
"use strict";
|
|
32
|
-
module.exports = {
|
|
33
|
-
testEnvironment: "jsdom",
|
|
34
|
-
setupFilesAfterEnv: ["<rootDir>/src/setup/jest.setup.ts"],
|
|
35
|
-
testMatch: [
|
|
36
|
-
"<rootDir>/src/**/*.test.ts",
|
|
37
|
-
"<rootDir>/src/**/*.test.tsx"
|
|
38
|
-
],
|
|
39
|
-
collectCoverageFrom: [
|
|
40
|
-
"src/**/*.{ts,tsx}",
|
|
41
|
-
"!src/**/*.test.{ts,tsx}",
|
|
42
|
-
"!src/**/*.stories.{ts,tsx}",
|
|
43
|
-
"!src/setup/**",
|
|
44
|
-
"!src/fixtures/**",
|
|
45
|
-
"!src/mocks/**"
|
|
46
|
-
],
|
|
47
|
-
coverageThreshold: {
|
|
48
|
-
global: {
|
|
49
|
-
branches: 80,
|
|
50
|
-
functions: 80,
|
|
51
|
-
lines: 80,
|
|
52
|
-
statements: 80
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
moduleNameMapper: {
|
|
56
|
-
"^@/(.*)$": "<rootDir>/src/$1",
|
|
57
|
-
"^@test/(.*)$": "<rootDir>/src/test-utils/$1",
|
|
58
|
-
"^@fixtures/(.*)$": "<rootDir>/src/fixtures/$1",
|
|
59
|
-
"^@mocks/(.*)$": "<rootDir>/src/mocks/$1"
|
|
60
|
-
},
|
|
61
|
-
transform: {
|
|
62
|
-
"^.+\\.(ts|tsx)$": "ts-jest"
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
2
|
|
|
68
3
|
// src/test-utils/test-utils.ts
|
|
69
4
|
import { expect as expect2 } from "@playwright/test";
|
|
@@ -699,13 +634,19 @@ configure({ testIdAttribute: "data-testid" });
|
|
|
699
634
|
global.TextEncoder = TextEncoder;
|
|
700
635
|
global.TextDecoder = TextDecoder;
|
|
701
636
|
global.IntersectionObserver = class IntersectionObserver {
|
|
702
|
-
constructor() {
|
|
637
|
+
constructor(_callback, _options) {
|
|
638
|
+
this.root = null;
|
|
639
|
+
this.rootMargin = "";
|
|
640
|
+
this.thresholds = [];
|
|
703
641
|
}
|
|
704
642
|
disconnect() {
|
|
705
643
|
}
|
|
706
|
-
observe() {
|
|
644
|
+
observe(_target) {
|
|
707
645
|
}
|
|
708
|
-
unobserve() {
|
|
646
|
+
unobserve(_target) {
|
|
647
|
+
}
|
|
648
|
+
takeRecords() {
|
|
649
|
+
return [];
|
|
709
650
|
}
|
|
710
651
|
};
|
|
711
652
|
global.ResizeObserver = class ResizeObserver {
|
|
@@ -733,20 +674,29 @@ Object.defineProperty(window, "matchMedia", {
|
|
|
733
674
|
dispatchEvent: jest.fn()
|
|
734
675
|
}))
|
|
735
676
|
});
|
|
736
|
-
var
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
677
|
+
var createStorageMock = () => {
|
|
678
|
+
const store = {};
|
|
679
|
+
return {
|
|
680
|
+
getItem: jest.fn((key) => store[key] ?? null),
|
|
681
|
+
setItem: jest.fn((key, value) => {
|
|
682
|
+
store[key] = value;
|
|
683
|
+
}),
|
|
684
|
+
removeItem: jest.fn((key) => {
|
|
685
|
+
delete store[key];
|
|
686
|
+
}),
|
|
687
|
+
clear: jest.fn(() => {
|
|
688
|
+
Object.keys(store).forEach((key) => delete store[key]);
|
|
689
|
+
}),
|
|
690
|
+
get length() {
|
|
691
|
+
return Object.keys(store).length;
|
|
692
|
+
},
|
|
693
|
+
key: jest.fn((index) => Object.keys(store)[index] ?? null)
|
|
694
|
+
};
|
|
748
695
|
};
|
|
749
|
-
|
|
696
|
+
var localStorageMock = createStorageMock();
|
|
697
|
+
Object.defineProperty(global, "localStorage", { value: localStorageMock, writable: true });
|
|
698
|
+
var sessionStorageMock = createStorageMock();
|
|
699
|
+
Object.defineProperty(global, "sessionStorage", { value: sessionStorageMock, writable: true });
|
|
750
700
|
global.fetch = jest.fn();
|
|
751
701
|
var originalError = console.error;
|
|
752
702
|
var originalWarn = console.warn;
|
|
@@ -778,58 +728,6 @@ afterEach(() => {
|
|
|
778
728
|
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
|
779
729
|
import { userEvent } from "@testing-library/user-event";
|
|
780
730
|
import { test, expect as expect3 } from "@playwright/test";
|
|
781
|
-
|
|
782
|
-
// playwright.config.ts
|
|
783
|
-
import { defineConfig, devices } from "@playwright/test";
|
|
784
|
-
var playwright_config_default = defineConfig({
|
|
785
|
-
testDir: "./src/playwright",
|
|
786
|
-
fullyParallel: true,
|
|
787
|
-
forbidOnly: !!process.env.CI,
|
|
788
|
-
retries: process.env.CI ? 2 : 0,
|
|
789
|
-
workers: process.env.CI ? 1 : void 0,
|
|
790
|
-
reporter: [
|
|
791
|
-
["html"],
|
|
792
|
-
["json", { outputFile: "test-results/results.json" }],
|
|
793
|
-
["junit", { outputFile: "test-results/results.xml" }]
|
|
794
|
-
],
|
|
795
|
-
use: {
|
|
796
|
-
baseURL: "http://localhost:3000",
|
|
797
|
-
trace: "on-first-retry",
|
|
798
|
-
screenshot: "only-on-failure",
|
|
799
|
-
video: "retain-on-failure"
|
|
800
|
-
},
|
|
801
|
-
projects: [
|
|
802
|
-
{
|
|
803
|
-
name: "chromium",
|
|
804
|
-
use: { ...devices["Desktop Chrome"] }
|
|
805
|
-
},
|
|
806
|
-
{
|
|
807
|
-
name: "firefox",
|
|
808
|
-
use: { ...devices["Desktop Firefox"] }
|
|
809
|
-
},
|
|
810
|
-
{
|
|
811
|
-
name: "webkit",
|
|
812
|
-
use: { ...devices["Desktop Safari"] }
|
|
813
|
-
},
|
|
814
|
-
{
|
|
815
|
-
name: "Mobile Chrome",
|
|
816
|
-
use: { ...devices["Pixel 5"] }
|
|
817
|
-
},
|
|
818
|
-
{
|
|
819
|
-
name: "Mobile Safari",
|
|
820
|
-
use: { ...devices["iPhone 12"] }
|
|
821
|
-
}
|
|
822
|
-
],
|
|
823
|
-
webServer: {
|
|
824
|
-
command: "npm run start:test",
|
|
825
|
-
url: "http://localhost:3000",
|
|
826
|
-
reuseExistingServer: !process.env.CI,
|
|
827
|
-
timeout: 120 * 1e3
|
|
828
|
-
}
|
|
829
|
-
});
|
|
830
|
-
|
|
831
|
-
// src/index.ts
|
|
832
|
-
var import_jest = __toESM(require_jest_config());
|
|
833
731
|
var TestRunner = class {
|
|
834
732
|
constructor(config) {
|
|
835
733
|
this.suites = [];
|
|
@@ -1038,7 +936,6 @@ var defaultTestConfig = {
|
|
|
1038
936
|
tablet: true,
|
|
1039
937
|
desktop: true
|
|
1040
938
|
};
|
|
1041
|
-
var export_jestConfig = import_jest.default;
|
|
1042
939
|
export {
|
|
1043
940
|
TestAssertions,
|
|
1044
941
|
TestDataGenerator,
|
|
@@ -1054,8 +951,6 @@ export {
|
|
|
1054
951
|
defaultTestConfig,
|
|
1055
952
|
expect3 as expect,
|
|
1056
953
|
fireEvent,
|
|
1057
|
-
export_jestConfig as jestConfig,
|
|
1058
|
-
playwright_config_default as playwrightConfig,
|
|
1059
954
|
render,
|
|
1060
955
|
screen,
|
|
1061
956
|
test,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../jest.config.js","../src/test-utils/test-utils.ts","../src/fixtures/index.ts","../src/setup/jest.setup.ts","../src/index.ts","../playwright.config.ts"],"sourcesContent":["module.exports = {\n testEnvironment: 'jsdom',\n setupFilesAfterEnv: ['<rootDir>/src/setup/jest.setup.ts'],\n testMatch: [\n '<rootDir>/src/**/*.test.ts',\n '<rootDir>/src/**/*.test.tsx'\n ],\n collectCoverageFrom: [\n 'src/**/*.{ts,tsx}',\n '!src/**/*.test.{ts,tsx}',\n '!src/**/*.stories.{ts,tsx}',\n '!src/setup/**',\n '!src/fixtures/**',\n '!src/mocks/**'\n ],\n coverageThreshold: {\n global: {\n branches: 80,\n functions: 80,\n lines: 80,\n statements: 80\n }\n },\n moduleNameMapper: {\n '^@/(.*)$': '<rootDir>/src/$1',\n '^@test/(.*)$': '<rootDir>/src/test-utils/$1',\n '^@fixtures/(.*)$': '<rootDir>/src/fixtures/$1',\n '^@mocks/(.*)$': '<rootDir>/src/mocks/$1'\n },\n transform: {\n '^.+\\\\.(ts|tsx)$': 'ts-jest'\n },\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { Page, BrowserContext, expect } from '@playwright/test';\n\nexport class TestUtils {\n constructor(\n public page: Page,\n public context: BrowserContext\n ) {}\n\n // Navigation helpers\n async navigateTo(path: string) {\n await this.page.goto(path);\n await this.page.waitForLoadState('networkidle');\n }\n\n async waitForElement(selector: string, timeout = 5000) {\n await this.page.waitForSelector(selector, { timeout });\n }\n\n async waitForText(text: string, timeout = 5000) {\n await this.page.waitForSelector(`text=${text}`, { timeout });\n }\n\n // Form helpers\n async fillForm(formData: Record<string, string>) {\n for (const [field, value] of Object.entries(formData)) {\n await this.page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n async clickButton(text: string) {\n await this.page.click(`button:has-text(\"${text}\")`);\n }\n\n async clickLink(text: string) {\n await this.page.click(`a:has-text(\"${text}\")`);\n }\n\n // Content management helpers\n async createContent(type: string, data: Record<string, any>) {\n await this.navigateTo('/admin/content/new');\n await this.page.selectOption('[name=\"contentType\"]', type);\n \n // Fill content fields\n await this.fillForm(data);\n \n // Save as draft\n await this.clickButton('Save as Draft');\n await this.waitForText('Content saved successfully');\n }\n\n async editContent(contentId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n \n // Fill updated fields\n await this.fillForm(updates);\n \n // Save changes\n await this.clickButton('Save Changes');\n await this.waitForText('Content updated successfully');\n }\n\n async publishContent(contentId: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Publish');\n await this.waitForText('Content published successfully');\n }\n\n async scheduleContent(contentId: string, date: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.page.fill('[name=\"publishDate\"]', date);\n await this.clickButton('Schedule');\n await this.waitForText('Content scheduled successfully');\n }\n\n async deleteContent(contentId: string, soft = true) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Delete');\n \n if (!soft) {\n await this.page.click('[data-testid=\"confirm-delete\"]');\n }\n \n await this.waitForText('Content deleted successfully');\n }\n\n // Workflow helpers\n async createWorkflow(workflowData: Record<string, any>) {\n await this.navigateTo('/admin/workflows/new');\n await this.fillForm(workflowData);\n await this.clickButton('Create Workflow');\n await this.waitForText('Workflow created successfully');\n }\n\n async updateWorkflow(workflowId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Workflow');\n await this.waitForText('Workflow updated successfully');\n }\n\n async deleteWorkflow(workflowId: string) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.clickButton('Delete Workflow');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Workflow deleted successfully');\n }\n\n // Content type helpers\n async createContentType(contentTypeData: Record<string, any>) {\n await this.navigateTo('/admin/content-types/new');\n await this.fillForm(contentTypeData);\n await this.clickButton('Create Content Type');\n await this.waitForText('Content type created successfully');\n }\n\n async updateContentType(contentTypeId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Content Type');\n await this.waitForText('Content type updated successfully');\n }\n\n async deleteContentType(contentTypeId: string) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.clickButton('Delete Content Type');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Content type deleted successfully');\n }\n\n // User helpers\n async createUser(userData: Record<string, any>) {\n await this.navigateTo('/admin/users/new');\n await this.fillForm(userData);\n await this.clickButton('Create User');\n await this.waitForText('User created successfully');\n }\n\n async updateUser(userId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update User');\n await this.waitForText('User updated successfully');\n }\n\n async deleteUser(userId: string) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.clickButton('Delete User');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('User deleted successfully');\n }\n\n // Authentication helpers\n async login(email: string, password: string) {\n await this.navigateTo('/login');\n await this.fillForm({ email, password });\n await this.clickButton('Login');\n await this.waitForText('Welcome');\n }\n\n async logout() {\n await this.clickButton('Logout');\n await this.waitForText('Logged out successfully');\n }\n\n // API helpers\n async apiRequest(method: string, endpoint: string, data?: any) {\n const response = await this.page.request.fetch(`/api${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n data: data ? JSON.stringify(data) : undefined,\n });\n \n return response;\n }\n\n async getContent(contentId: string) {\n const response = await this.apiRequest('GET', `/content/${contentId}`);\n return response.json();\n }\n\n async createContentViaAPI(type: string, data: Record<string, any>) {\n const response = await this.apiRequest('POST', '/content', { type, data });\n return response.json();\n }\n\n async updateContentViaAPI(contentId: string, data: Record<string, any>) {\n const response = await this.apiRequest('PUT', `/content/${contentId}`, { data });\n return response.json();\n }\n\n async deleteContentViaAPI(contentId: string, soft = true) {\n const response = await this.apiRequest('DELETE', `/content/${contentId}?soft=${soft}`);\n return response;\n }\n\n // Assertion helpers\n async expectElementVisible(selector: string) {\n await expect(this.page.locator(selector)).toBeVisible();\n }\n\n async expectElementHidden(selector: string) {\n await expect(this.page.locator(selector)).toBeHidden();\n }\n\n async expectTextVisible(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeVisible();\n }\n\n async expectTextHidden(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeHidden();\n }\n\n async expectElementCount(selector: string, count: number) {\n await expect(this.page.locator(selector)).toHaveCount(count);\n }\n\n async expectElementText(selector: string, text: string) {\n await expect(this.page.locator(selector)).toHaveText(text);\n }\n\n async expectElementValue(selector: string, value: string) {\n await expect(this.page.locator(selector)).toHaveValue(value);\n }\n\n // Screenshot helpers\n async takeScreenshot(name: string) {\n await this.page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n async takeElementScreenshot(selector: string, name: string) {\n await this.page.locator(selector).screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n // Performance helpers\n async measurePerformance(name: string, fn: () => Promise<void>) {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n\n // Accessibility helpers\n async checkAccessibility() {\n // This would integrate with axe-core or similar\n // For now, just check for basic accessibility attributes\n const elements = await this.page.locator('[role]').all();\n expect(elements.length).toBeGreaterThan(0);\n }\n\n // Mobile helpers\n async switchToMobile() {\n await this.page.setViewportSize({ width: 375, height: 667 });\n }\n\n async switchToTablet() {\n await this.page.setViewportSize({ width: 768, height: 1024 });\n }\n\n async switchToDesktop() {\n await this.page.setViewportSize({ width: 1920, height: 1080 });\n }\n\n // Cleanup helpers\n async cleanup() {\n // Clean up any test data\n await this.page.evaluate(() => {\n localStorage.clear();\n sessionStorage.clear();\n });\n }\n}\n\n// Export factory function\nexport function createTestUtils(page: Page, context: BrowserContext) {\n return new TestUtils(page, context);\n}\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { faker } from '@faker-js/faker';\nimport { v4 as uuidv4 } from 'uuid';\nimport { format, addDays, subDays } from 'date-fns';\n\n// Content fixtures\nexport const contentFixtures = {\n text: {\n id: uuidv4(),\n type: 'text',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n body: faker.lorem.paragraphs(3),\n excerpt: faker.lorem.sentence(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['general'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n image: {\n id: uuidv4(),\n type: 'image',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n altText: faker.lorem.sentence(),\n imageUrl: faker.image.url(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['photography'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n audio: {\n id: uuidv4(),\n type: 'audio',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n audioUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n metadata: {\n artist: faker.person.fullName(),\n album: faker.lorem.words(2),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['podcast'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n video: {\n id: uuidv4(),\n type: 'video',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n videoUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n dimensions: {\n width: 1920,\n height: 1080\n },\n metadata: {\n director: faker.person.fullName(),\n genre: faker.lorem.word(),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['tutorial'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n }\n};\n\n// Workflow fixtures\nexport const workflowFixtures = {\n simple: {\n id: 'simple',\n name: 'Simple Workflow',\n description: 'A simple two-stage workflow',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n },\n\n editorial: {\n id: 'editorial',\n name: 'Editorial Workflow',\n description: 'A comprehensive editorial workflow',\n stages: [\n {\n id: 'write',\n name: 'Write',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'edit',\n name: 'Edit',\n order: 2,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'review',\n name: 'Review',\n order: 3,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.review']\n },\n {\n id: 'publish',\n name: 'Publish',\n order: 4,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'write-to-edit',\n from: 'write',\n to: 'edit',\n permissions: ['content.edit']\n },\n {\n id: 'edit-to-review',\n from: 'edit',\n to: 'review',\n permissions: ['content.review']\n },\n {\n id: 'review-to-publish',\n from: 'review',\n to: 'publish',\n permissions: ['content.publish']\n }\n ]\n }\n};\n\n// User fixtures\nexport const userFixtures = {\n admin: {\n id: uuidv4(),\n name: 'Admin User',\n email: 'admin@example.com',\n role: 'admin',\n permissions: ['*'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n editor: {\n id: uuidv4(),\n name: 'Editor User',\n email: 'editor@example.com',\n role: 'editor',\n permissions: ['content.edit', 'content.publish', 'content.schedule'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n author: {\n id: uuidv4(),\n name: 'Author User',\n email: 'author@example.com',\n role: 'author',\n permissions: ['content.edit'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n user: {\n id: uuidv4(),\n name: 'Regular User',\n email: 'user@example.com',\n role: 'user',\n permissions: ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n }\n};\n\n// Content type fixtures\nexport const contentTypeFixtures = {\n text: {\n id: 'text',\n name: 'Text Content',\n description: 'Rich text content with formatting',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n body: { type: 'string', required: true },\n excerpt: { type: 'string', required: false },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'TextEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'body', type: 'textarea', label: 'Body', required: true },\n { name: 'excerpt', type: 'textarea', label: 'Excerpt', required: false },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n },\n\n image: {\n id: 'image',\n name: 'Image Content',\n description: 'Image content with metadata',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n description: { type: 'string', required: false },\n altText: { type: 'string', required: true },\n imageUrl: { type: 'string', required: true },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'ImageEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'description', type: 'textarea', label: 'Description', required: false },\n { name: 'altText', type: 'text', label: 'Alt Text', required: true },\n { name: 'imageUrl', type: 'url', label: 'Image URL', required: true },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n }\n};\n\n// Configuration fixtures\nexport const configFixtures = {\n development: {\n server: {\n port: 3000,\n host: 'localhost',\n cors: {\n origin: '*',\n credentials: true\n }\n },\n database: {\n type: 'sqlite',\n name: 'content_management_dev'\n },\n logging: {\n level: 'debug',\n format: 'text',\n console: {\n enabled: true,\n colorize: true\n }\n }\n },\n\n production: {\n server: {\n port: 80,\n host: '0.0.0.0',\n cors: {\n origin: ['https://myapp.com'],\n credentials: true\n }\n },\n database: {\n type: 'postgresql',\n url: 'postgresql://user:password@localhost:5432/content_management'\n },\n logging: {\n level: 'info',\n format: 'json',\n file: {\n enabled: true,\n path: './logs',\n maxSize: '10MB',\n maxFiles: 5\n }\n }\n }\n};\n\n// Test data generators\nexport const testDataGenerators = {\n generateContent: (type: string, overrides: any = {}) => {\n const base = contentFixtures[type as keyof typeof contentFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateWorkflow: (overrides: any = {}) => {\n return {\n ...workflowFixtures.simple,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateUser: (role: string = 'user', overrides: any = {}) => {\n const base = userFixtures[role as keyof typeof userFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateContentType: (overrides: any = {}) => {\n return {\n ...contentTypeFixtures.text,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateConfig: (environment: string = 'development', overrides: any = {}) => {\n const base = configFixtures[environment as keyof typeof configFixtures];\n return {\n ...base,\n ...overrides\n };\n }\n};\n\n// Date fixtures\nexport const dateFixtures = {\n now: new Date(),\n tomorrow: addDays(new Date(), 1),\n yesterday: subDays(new Date(), 1),\n nextWeek: addDays(new Date(), 7),\n lastWeek: subDays(new Date(), 7),\n nextMonth: addDays(new Date(), 30),\n lastMonth: subDays(new Date(), 30)\n};\n\n// API response fixtures\nexport const apiResponseFixtures = {\n success: {\n success: true,\n message: 'Operation completed successfully',\n data: null\n },\n\n error: {\n success: false,\n message: 'An error occurred',\n error: {\n code: 'INTERNAL_ERROR',\n details: 'Something went wrong'\n }\n },\n\n validationError: {\n success: false,\n message: 'Validation failed',\n error: {\n code: 'VALIDATION_ERROR',\n details: {\n field: 'title',\n message: 'Title is required'\n }\n }\n }\n};\n\n// Export all fixtures\nexport default {\n content: contentFixtures,\n workflow: workflowFixtures,\n user: userFixtures,\n contentType: contentTypeFixtures,\n config: configFixtures,\n date: dateFixtures,\n apiResponse: apiResponseFixtures,\n generators: testDataGenerators\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport '@testing-library/jest-dom';\nimport { configure } from '@testing-library/react';\nimport { TextEncoder, TextDecoder } from 'util';\n\n// Configure testing library\nconfigure({ testIdAttribute: 'data-testid' });\n\n// Polyfills for Node.js environment\nglobal.TextEncoder = TextEncoder;\nglobal.TextDecoder = TextDecoder as any;\n\n// Mock IntersectionObserver\nglobal.IntersectionObserver = class IntersectionObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock ResizeObserver\nglobal.ResizeObserver = class ResizeObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock matchMedia\nObject.defineProperty(window, 'matchMedia', {\n writable: true,\n value: jest.fn().mockImplementation(query => ({\n matches: false,\n media: query,\n onchange: null,\n addListener: jest.fn(), // deprecated\n removeListener: jest.fn(), // deprecated\n addEventListener: jest.fn(),\n removeEventListener: jest.fn(),\n dispatchEvent: jest.fn(),\n })),\n});\n\n// Mock localStorage\nconst localStorageMock = {\n getItem: jest.fn(),\n setItem: jest.fn(),\n removeItem: jest.fn(),\n clear: jest.fn(),\n};\nglobal.localStorage = localStorageMock;\n\n// Mock sessionStorage\nconst sessionStorageMock = {\n getItem: jest.fn(),\n setItem: jest.fn(),\n removeItem: jest.fn(),\n clear: jest.fn(),\n};\nglobal.sessionStorage = sessionStorageMock;\n\n// Mock fetch\nglobal.fetch = jest.fn();\n\n// Mock console methods to reduce noise in tests\nconst originalError = console.error;\nconst originalWarn = console.warn;\n\nbeforeAll(() => {\n console.error = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalError.call(console, ...args);\n };\n\n console.warn = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalWarn.call(console, ...args);\n };\n});\n\nafterAll(() => {\n console.error = originalError;\n console.warn = originalWarn;\n});\n\n// Clean up after each test\nafterEach(() => {\n jest.clearAllMocks();\n localStorageMock.clear();\n sessionStorageMock.clear();\n});\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\n// Test utilities\nexport * from './test-utils/test-utils';\n\n// Test fixtures\nexport * from './fixtures';\n\n// Test setup\nexport * from './setup/jest.setup';\n\n// Re-export testing libraries for convenience\nexport { render, screen, fireEvent, waitFor } from '@testing-library/react';\nexport { userEvent } from '@testing-library/user-event';\nexport { test, expect } from '@playwright/test';\n\n// Test configuration\nexport { default as playwrightConfig } from '../playwright.config';\nexport { default as jestConfig } from '../jest.config';\n\n// Test types\nexport interface TestConfig {\n baseURL: string;\n timeout: number;\n retries: number;\n workers: number;\n reporter: string[];\n browser: string[];\n mobile: boolean;\n tablet: boolean;\n desktop: boolean;\n}\n\nexport interface TestSuite {\n name: string;\n description: string;\n tests: TestCase[];\n setup?: () => Promise<void>;\n teardown?: () => Promise<void>;\n}\n\nexport interface TestCase {\n name: string;\n description: string;\n test: () => Promise<void>;\n timeout?: number;\n retries?: number;\n skip?: boolean;\n only?: boolean;\n}\n\nexport interface TestResult {\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: Error;\n screenshots?: string[];\n video?: string;\n trace?: string;\n}\n\nexport interface TestReport {\n suite: string;\n results: TestResult[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n };\n}\n\n// Test runner utilities\nexport class TestRunner {\n private config: TestConfig;\n private suites: TestSuite[] = [];\n\n constructor(config: TestConfig) {\n this.config = config;\n }\n\n addSuite(suite: TestSuite): void {\n this.suites.push(suite);\n }\n\n async runSuite(suiteName: string): Promise<TestReport> {\n const suite = this.suites.find(s => s.name === suiteName);\n if (!suite) {\n throw new Error(`Suite ${suiteName} not found`);\n }\n\n const results: TestResult[] = [];\n const startTime = Date.now();\n\n try {\n if (suite.setup) {\n await suite.setup();\n }\n\n for (const testCase of suite.tests) {\n if (testCase.skip) {\n results.push({\n name: testCase.name,\n status: 'skipped',\n duration: 0\n });\n continue;\n }\n\n const testStartTime = Date.now();\n try {\n await testCase.test();\n results.push({\n name: testCase.name,\n status: 'passed',\n duration: Date.now() - testStartTime\n });\n } catch (error) {\n results.push({\n name: testCase.name,\n status: 'failed',\n duration: Date.now() - testStartTime,\n error: error as Error\n });\n }\n }\n } finally {\n if (suite.teardown) {\n await suite.teardown();\n }\n }\n\n const summary = {\n total: results.length,\n passed: results.filter(r => r.status === 'passed').length,\n failed: results.filter(r => r.status === 'failed').length,\n skipped: results.filter(r => r.status === 'skipped').length,\n duration: Date.now() - startTime\n };\n\n return {\n suite: suiteName,\n results,\n summary\n };\n }\n\n async runAllSuites(): Promise<TestReport[]> {\n const reports: TestReport[] = [];\n \n for (const suite of this.suites) {\n const report = await this.runSuite(suite.name);\n reports.push(report);\n }\n\n return reports;\n }\n}\n\n// Test data generators\nexport class TestDataGenerator {\n static generateContent(type: string, overrides: any = {}): any {\n const base = {\n id: `test-${Date.now()}`,\n type,\n title: `Test ${type} Content`,\n slug: `test-${type}-content`,\n body: `Test content for ${type}`,\n author: {\n id: 'test-user',\n name: 'Test User',\n email: 'test@example.com'\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n\n static generateWorkflow(overrides: any = {}): any {\n const base = {\n id: `test-workflow-${Date.now()}`,\n name: 'Test Workflow',\n description: 'Test workflow for testing',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n };\n\n return { ...base, ...overrides };\n }\n\n static generateUser(role: string = 'user', overrides: any = {}): any {\n const base = {\n id: `test-user-${Date.now()}`,\n name: 'Test User',\n email: 'test@example.com',\n role,\n permissions: role === 'admin' ? ['*'] : ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n}\n\n// Test assertions\nexport class TestAssertions {\n static async expectElementVisible(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeVisible();\n }\n\n static async expectElementHidden(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeHidden();\n }\n\n static async expectTextVisible(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeVisible();\n }\n\n static async expectTextHidden(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeHidden();\n }\n\n static async expectElementCount(page: any, selector: string, count: number): Promise<void> {\n const elements = await page.locator(selector);\n await expect(elements).toHaveCount(count);\n }\n\n static async expectElementText(page: any, selector: string, text: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveText(text);\n }\n\n static async expectElementValue(page: any, selector: string, value: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveValue(value);\n }\n}\n\n// Test helpers\nexport class TestHelpers {\n static async waitForElement(page: any, selector: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(selector, { timeout });\n }\n\n static async waitForText(page: any, text: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(`text=${text}`, { timeout });\n }\n\n static async fillForm(page: any, formData: Record<string, string>): Promise<void> {\n for (const [field, value] of Object.entries(formData)) {\n await page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n static async clickButton(page: any, text: string): Promise<void> {\n await page.click(`button:has-text(\"${text}\")`);\n }\n\n static async clickLink(page: any, text: string): Promise<void> {\n await page.click(`a:has-text(\"${text}\")`);\n }\n\n static async takeScreenshot(page: any, name: string): Promise<void> {\n await page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n static async measurePerformance(name: string, fn: () => Promise<void>): Promise<number> {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n}\n\n// Export default configuration\nexport const defaultTestConfig: TestConfig = {\n baseURL: 'http://localhost:3000',\n timeout: 30000,\n retries: 2,\n workers: 1,\n reporter: ['html', 'json'],\n browser: ['chromium', 'firefox', 'webkit'],\n mobile: true,\n tablet: true,\n desktop: true\n};\n","import { defineConfig, devices } from '@playwright/test';\n\nexport default defineConfig({\n testDir: './src/playwright',\n fullyParallel: true,\n forbidOnly: !!process.env.CI,\n retries: process.env.CI ? 2 : 0,\n workers: process.env.CI ? 1 : undefined,\n reporter: [\n ['html'],\n ['json', { outputFile: 'test-results/results.json' }],\n ['junit', { outputFile: 'test-results/results.xml' }]\n ],\n use: {\n baseURL: 'http://localhost:3000',\n trace: 'on-first-retry',\n screenshot: 'only-on-failure',\n video: 'retain-on-failure'\n },\n projects: [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] }\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] }\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] }\n },\n {\n name: 'Mobile Chrome',\n use: { ...devices['Pixel 5'] }\n },\n {\n name: 'Mobile Safari',\n use: { ...devices['iPhone 12'] }\n }\n ],\n webServer: {\n command: 'npm run start:test',\n url: 'http://localhost:3000',\n reuseExistingServer: !process.env.CI,\n timeout: 120 * 1000\n }\n});\n"],"mappings":"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","names":["expect","expect"]}
|
|
1
|
+
{"version":3,"sources":["../src/test-utils/test-utils.ts","../src/fixtures/index.ts","../src/setup/jest.setup.ts","../src/index.ts"],"sourcesContent":["/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { Page, BrowserContext, expect } from '@playwright/test';\n\nexport class TestUtils {\n constructor(\n public page: Page,\n public context: BrowserContext\n ) {}\n\n // Navigation helpers\n async navigateTo(path: string) {\n await this.page.goto(path);\n await this.page.waitForLoadState('networkidle');\n }\n\n async waitForElement(selector: string, timeout = 5000) {\n await this.page.waitForSelector(selector, { timeout });\n }\n\n async waitForText(text: string, timeout = 5000) {\n await this.page.waitForSelector(`text=${text}`, { timeout });\n }\n\n // Form helpers\n async fillForm(formData: Record<string, string>) {\n for (const [field, value] of Object.entries(formData)) {\n await this.page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n async clickButton(text: string) {\n await this.page.click(`button:has-text(\"${text}\")`);\n }\n\n async clickLink(text: string) {\n await this.page.click(`a:has-text(\"${text}\")`);\n }\n\n // Content management helpers\n async createContent(type: string, data: Record<string, any>) {\n await this.navigateTo('/admin/content/new');\n await this.page.selectOption('[name=\"contentType\"]', type);\n \n // Fill content fields\n await this.fillForm(data);\n \n // Save as draft\n await this.clickButton('Save as Draft');\n await this.waitForText('Content saved successfully');\n }\n\n async editContent(contentId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n \n // Fill updated fields\n await this.fillForm(updates);\n \n // Save changes\n await this.clickButton('Save Changes');\n await this.waitForText('Content updated successfully');\n }\n\n async publishContent(contentId: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Publish');\n await this.waitForText('Content published successfully');\n }\n\n async scheduleContent(contentId: string, date: string) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.page.fill('[name=\"publishDate\"]', date);\n await this.clickButton('Schedule');\n await this.waitForText('Content scheduled successfully');\n }\n\n async deleteContent(contentId: string, soft = true) {\n await this.navigateTo(`/admin/content/${contentId}/edit`);\n await this.clickButton('Delete');\n \n if (!soft) {\n await this.page.click('[data-testid=\"confirm-delete\"]');\n }\n \n await this.waitForText('Content deleted successfully');\n }\n\n // Workflow helpers\n async createWorkflow(workflowData: Record<string, any>) {\n await this.navigateTo('/admin/workflows/new');\n await this.fillForm(workflowData);\n await this.clickButton('Create Workflow');\n await this.waitForText('Workflow created successfully');\n }\n\n async updateWorkflow(workflowId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Workflow');\n await this.waitForText('Workflow updated successfully');\n }\n\n async deleteWorkflow(workflowId: string) {\n await this.navigateTo(`/admin/workflows/${workflowId}/edit`);\n await this.clickButton('Delete Workflow');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Workflow deleted successfully');\n }\n\n // Content type helpers\n async createContentType(contentTypeData: Record<string, any>) {\n await this.navigateTo('/admin/content-types/new');\n await this.fillForm(contentTypeData);\n await this.clickButton('Create Content Type');\n await this.waitForText('Content type created successfully');\n }\n\n async updateContentType(contentTypeId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update Content Type');\n await this.waitForText('Content type updated successfully');\n }\n\n async deleteContentType(contentTypeId: string) {\n await this.navigateTo(`/admin/content-types/${contentTypeId}/edit`);\n await this.clickButton('Delete Content Type');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('Content type deleted successfully');\n }\n\n // User helpers\n async createUser(userData: Record<string, any>) {\n await this.navigateTo('/admin/users/new');\n await this.fillForm(userData);\n await this.clickButton('Create User');\n await this.waitForText('User created successfully');\n }\n\n async updateUser(userId: string, updates: Record<string, any>) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.fillForm(updates);\n await this.clickButton('Update User');\n await this.waitForText('User updated successfully');\n }\n\n async deleteUser(userId: string) {\n await this.navigateTo(`/admin/users/${userId}/edit`);\n await this.clickButton('Delete User');\n await this.page.click('[data-testid=\"confirm-delete\"]');\n await this.waitForText('User deleted successfully');\n }\n\n // Authentication helpers\n async login(email: string, password: string) {\n await this.navigateTo('/login');\n await this.fillForm({ email, password });\n await this.clickButton('Login');\n await this.waitForText('Welcome');\n }\n\n async logout() {\n await this.clickButton('Logout');\n await this.waitForText('Logged out successfully');\n }\n\n // API helpers\n async apiRequest(method: string, endpoint: string, data?: any) {\n const response = await this.page.request.fetch(`/api${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n data: data ? JSON.stringify(data) : undefined,\n });\n \n return response;\n }\n\n async getContent(contentId: string) {\n const response = await this.apiRequest('GET', `/content/${contentId}`);\n return response.json();\n }\n\n async createContentViaAPI(type: string, data: Record<string, any>) {\n const response = await this.apiRequest('POST', '/content', { type, data });\n return response.json();\n }\n\n async updateContentViaAPI(contentId: string, data: Record<string, any>) {\n const response = await this.apiRequest('PUT', `/content/${contentId}`, { data });\n return response.json();\n }\n\n async deleteContentViaAPI(contentId: string, soft = true) {\n const response = await this.apiRequest('DELETE', `/content/${contentId}?soft=${soft}`);\n return response;\n }\n\n // Assertion helpers\n async expectElementVisible(selector: string) {\n await expect(this.page.locator(selector)).toBeVisible();\n }\n\n async expectElementHidden(selector: string) {\n await expect(this.page.locator(selector)).toBeHidden();\n }\n\n async expectTextVisible(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeVisible();\n }\n\n async expectTextHidden(text: string) {\n await expect(this.page.locator(`text=${text}`)).toBeHidden();\n }\n\n async expectElementCount(selector: string, count: number) {\n await expect(this.page.locator(selector)).toHaveCount(count);\n }\n\n async expectElementText(selector: string, text: string) {\n await expect(this.page.locator(selector)).toHaveText(text);\n }\n\n async expectElementValue(selector: string, value: string) {\n await expect(this.page.locator(selector)).toHaveValue(value);\n }\n\n // Screenshot helpers\n async takeScreenshot(name: string) {\n await this.page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n async takeElementScreenshot(selector: string, name: string) {\n await this.page.locator(selector).screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n // Performance helpers\n async measurePerformance(name: string, fn: () => Promise<void>) {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n\n // Accessibility helpers\n async checkAccessibility() {\n // This would integrate with axe-core or similar\n // For now, just check for basic accessibility attributes\n const elements = await this.page.locator('[role]').all();\n expect(elements.length).toBeGreaterThan(0);\n }\n\n // Mobile helpers\n async switchToMobile() {\n await this.page.setViewportSize({ width: 375, height: 667 });\n }\n\n async switchToTablet() {\n await this.page.setViewportSize({ width: 768, height: 1024 });\n }\n\n async switchToDesktop() {\n await this.page.setViewportSize({ width: 1920, height: 1080 });\n }\n\n // Cleanup helpers\n async cleanup() {\n // Clean up any test data\n await this.page.evaluate(() => {\n localStorage.clear();\n sessionStorage.clear();\n });\n }\n}\n\n// Export factory function\nexport function createTestUtils(page: Page, context: BrowserContext) {\n return new TestUtils(page, context);\n}\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport { faker } from '@faker-js/faker';\nimport { v4 as uuidv4 } from 'uuid';\nimport { format, addDays, subDays } from 'date-fns';\n\n// Content fixtures\nexport const contentFixtures = {\n text: {\n id: uuidv4(),\n type: 'text',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n body: faker.lorem.paragraphs(3),\n excerpt: faker.lorem.sentence(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['general'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n image: {\n id: uuidv4(),\n type: 'image',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n altText: faker.lorem.sentence(),\n imageUrl: faker.image.url(),\n tags: faker.lorem.words(3).split(' '),\n categories: ['photography'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n audio: {\n id: uuidv4(),\n type: 'audio',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n audioUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n metadata: {\n artist: faker.person.fullName(),\n album: faker.lorem.words(2),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['podcast'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n },\n\n video: {\n id: uuidv4(),\n type: 'video',\n title: faker.lorem.sentence(),\n slug: faker.lorem.slug(),\n description: faker.lorem.sentence(),\n videoUrl: faker.internet.url(),\n duration: faker.number.int({ min: 60, max: 3600 }),\n dimensions: {\n width: 1920,\n height: 1080\n },\n metadata: {\n director: faker.person.fullName(),\n genre: faker.lorem.word(),\n year: faker.date.past().getFullYear()\n },\n tags: faker.lorem.words(3).split(' '),\n categories: ['tutorial'],\n author: {\n id: uuidv4(),\n name: faker.person.fullName(),\n email: faker.internet.email()\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date(),\n publishedAt: null\n }\n};\n\n// Workflow fixtures\nexport const workflowFixtures = {\n simple: {\n id: 'simple',\n name: 'Simple Workflow',\n description: 'A simple two-stage workflow',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n },\n\n editorial: {\n id: 'editorial',\n name: 'Editorial Workflow',\n description: 'A comprehensive editorial workflow',\n stages: [\n {\n id: 'write',\n name: 'Write',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'edit',\n name: 'Edit',\n order: 2,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'review',\n name: 'Review',\n order: 3,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.review']\n },\n {\n id: 'publish',\n name: 'Publish',\n order: 4,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'write-to-edit',\n from: 'write',\n to: 'edit',\n permissions: ['content.edit']\n },\n {\n id: 'edit-to-review',\n from: 'edit',\n to: 'review',\n permissions: ['content.review']\n },\n {\n id: 'review-to-publish',\n from: 'review',\n to: 'publish',\n permissions: ['content.publish']\n }\n ]\n }\n};\n\n// User fixtures\nexport const userFixtures = {\n admin: {\n id: uuidv4(),\n name: 'Admin User',\n email: 'admin@example.com',\n role: 'admin',\n permissions: ['*'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n editor: {\n id: uuidv4(),\n name: 'Editor User',\n email: 'editor@example.com',\n role: 'editor',\n permissions: ['content.edit', 'content.publish', 'content.schedule'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n author: {\n id: uuidv4(),\n name: 'Author User',\n email: 'author@example.com',\n role: 'author',\n permissions: ['content.edit'],\n createdAt: new Date(),\n updatedAt: new Date()\n },\n\n user: {\n id: uuidv4(),\n name: 'Regular User',\n email: 'user@example.com',\n role: 'user',\n permissions: ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n }\n};\n\n// Content type fixtures\nexport const contentTypeFixtures = {\n text: {\n id: 'text',\n name: 'Text Content',\n description: 'Rich text content with formatting',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n body: { type: 'string', required: true },\n excerpt: { type: 'string', required: false },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'TextEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'body', type: 'textarea', label: 'Body', required: true },\n { name: 'excerpt', type: 'textarea', label: 'Excerpt', required: false },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n },\n\n image: {\n id: 'image',\n name: 'Image Content',\n description: 'Image content with metadata',\n schema: {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true },\n description: { type: 'string', required: false },\n altText: { type: 'string', required: true },\n imageUrl: { type: 'string', required: true },\n tags: { type: 'array', required: false },\n categories: { type: 'array', required: false }\n },\n editorConfig: {\n component: 'ImageEditor',\n fields: [\n { name: 'title', type: 'text', label: 'Title', required: true },\n { name: 'slug', type: 'text', label: 'Slug', required: true },\n { name: 'description', type: 'textarea', label: 'Description', required: false },\n { name: 'altText', type: 'text', label: 'Alt Text', required: true },\n { name: 'imageUrl', type: 'url', label: 'Image URL', required: true },\n { name: 'tags', type: 'tags', label: 'Tags', required: false },\n { name: 'categories', type: 'select', label: 'Categories', required: false }\n ]\n }\n }\n};\n\n// Configuration fixtures\nexport const configFixtures = {\n development: {\n server: {\n port: 3000,\n host: 'localhost',\n cors: {\n origin: '*',\n credentials: true\n }\n },\n database: {\n type: 'sqlite',\n name: 'content_management_dev'\n },\n logging: {\n level: 'debug',\n format: 'text',\n console: {\n enabled: true,\n colorize: true\n }\n }\n },\n\n production: {\n server: {\n port: 80,\n host: '0.0.0.0',\n cors: {\n origin: ['https://myapp.com'],\n credentials: true\n }\n },\n database: {\n type: 'postgresql',\n url: 'postgresql://user:password@localhost:5432/content_management'\n },\n logging: {\n level: 'info',\n format: 'json',\n file: {\n enabled: true,\n path: './logs',\n maxSize: '10MB',\n maxFiles: 5\n }\n }\n }\n};\n\n// Test data generators\nexport const testDataGenerators = {\n generateContent: (type: string, overrides: any = {}) => {\n const base = contentFixtures[type as keyof typeof contentFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateWorkflow: (overrides: any = {}) => {\n return {\n ...workflowFixtures.simple,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateUser: (role: string = 'user', overrides: any = {}) => {\n const base = userFixtures[role as keyof typeof userFixtures];\n return {\n ...base,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateContentType: (overrides: any = {}) => {\n return {\n ...contentTypeFixtures.text,\n id: uuidv4(),\n ...overrides\n };\n },\n\n generateConfig: (environment: string = 'development', overrides: any = {}) => {\n const base = configFixtures[environment as keyof typeof configFixtures];\n return {\n ...base,\n ...overrides\n };\n }\n};\n\n// Date fixtures\nexport const dateFixtures = {\n now: new Date(),\n tomorrow: addDays(new Date(), 1),\n yesterday: subDays(new Date(), 1),\n nextWeek: addDays(new Date(), 7),\n lastWeek: subDays(new Date(), 7),\n nextMonth: addDays(new Date(), 30),\n lastMonth: subDays(new Date(), 30)\n};\n\n// API response fixtures\nexport const apiResponseFixtures = {\n success: {\n success: true,\n message: 'Operation completed successfully',\n data: null\n },\n\n error: {\n success: false,\n message: 'An error occurred',\n error: {\n code: 'INTERNAL_ERROR',\n details: 'Something went wrong'\n }\n },\n\n validationError: {\n success: false,\n message: 'Validation failed',\n error: {\n code: 'VALIDATION_ERROR',\n details: {\n field: 'title',\n message: 'Title is required'\n }\n }\n }\n};\n\n// Export all fixtures\nexport default {\n content: contentFixtures,\n workflow: workflowFixtures,\n user: userFixtures,\n contentType: contentTypeFixtures,\n config: configFixtures,\n date: dateFixtures,\n apiResponse: apiResponseFixtures,\n generators: testDataGenerators\n};\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\nimport '@testing-library/jest-dom';\nimport { configure } from '@testing-library/react';\nimport { TextEncoder, TextDecoder } from 'util';\n\n// Configure testing library\nconfigure({ testIdAttribute: 'data-testid' });\n\n// Polyfills for Node.js environment\nglobal.TextEncoder = TextEncoder as unknown as typeof globalThis.TextEncoder;\nglobal.TextDecoder = TextDecoder as unknown as typeof globalThis.TextDecoder;\n\n// Mock IntersectionObserver\nglobal.IntersectionObserver = class IntersectionObserver implements globalThis.IntersectionObserver {\n readonly root: Element | Document | null = null;\n readonly rootMargin: string = '';\n readonly thresholds: ReadonlyArray<number> = [];\n constructor(_callback: IntersectionObserverCallback, _options?: IntersectionObserverInit) {}\n disconnect(): void {}\n observe(_target: Element): void {}\n unobserve(_target: Element): void {}\n takeRecords(): IntersectionObserverEntry[] { return []; }\n};\n\n// Mock ResizeObserver\nglobal.ResizeObserver = class ResizeObserver {\n constructor() {}\n disconnect() {}\n observe() {}\n unobserve() {}\n};\n\n// Mock matchMedia\nObject.defineProperty(window, 'matchMedia', {\n writable: true,\n value: jest.fn().mockImplementation(query => ({\n matches: false,\n media: query,\n onchange: null,\n addListener: jest.fn(), // deprecated\n removeListener: jest.fn(), // deprecated\n addEventListener: jest.fn(),\n removeEventListener: jest.fn(),\n dispatchEvent: jest.fn(),\n })),\n});\n\n// Mock localStorage\nconst createStorageMock = (): Storage => {\n const store: Record<string, string> = {};\n return {\n getItem: jest.fn((key: string) => store[key] ?? null),\n setItem: jest.fn((key: string, value: string) => { store[key] = value; }),\n removeItem: jest.fn((key: string) => { delete store[key]; }),\n clear: jest.fn(() => { Object.keys(store).forEach(key => delete store[key]); }),\n get length() { return Object.keys(store).length; },\n key: jest.fn((index: number) => Object.keys(store)[index] ?? null),\n };\n};\nconst localStorageMock = createStorageMock();\nObject.defineProperty(global, 'localStorage', { value: localStorageMock, writable: true });\n\n// Mock sessionStorage\nconst sessionStorageMock = createStorageMock();\nObject.defineProperty(global, 'sessionStorage', { value: sessionStorageMock, writable: true });\n\n// Mock fetch\nglobal.fetch = jest.fn();\n\n// Mock console methods to reduce noise in tests\nconst originalError = console.error;\nconst originalWarn = console.warn;\n\nbeforeAll(() => {\n console.error = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalError.call(console, ...args);\n };\n\n console.warn = (...args: any[]) => {\n if (\n typeof args[0] === 'string' &&\n args[0].includes('Warning: ReactDOM.render is no longer supported')\n ) {\n return;\n }\n originalWarn.call(console, ...args);\n };\n});\n\nafterAll(() => {\n console.error = originalError;\n console.warn = originalWarn;\n});\n\n// Clean up after each test\nafterEach(() => {\n jest.clearAllMocks();\n localStorageMock.clear();\n sessionStorageMock.clear();\n});\n","/*\nCopyright (c) 2025 Bernier LLC\n\nThis file is licensed to the client under a limited-use license.\nThe client may use and modify this code *only within the scope of the project it was delivered for*.\nRedistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n*/\n\n// Test utilities\nexport * from './test-utils/test-utils';\n\n// Test fixtures\nexport * from './fixtures';\n\n// Test setup\nexport * from './setup/jest.setup';\n\n// Re-export testing libraries for convenience\nexport { render, screen, fireEvent, waitFor } from '@testing-library/react';\nexport { userEvent } from '@testing-library/user-event';\nexport { test, expect } from '@playwright/test';\n\n// Note: Test configuration files (playwright.config, jest.config) are not exported\n// as they exist outside the src directory. Import them directly if needed.\n\n// Test types\nexport interface TestConfig {\n baseURL: string;\n timeout: number;\n retries: number;\n workers: number;\n reporter: string[];\n browser: string[];\n mobile: boolean;\n tablet: boolean;\n desktop: boolean;\n}\n\nexport interface TestSuite {\n name: string;\n description: string;\n tests: TestCase[];\n setup?: () => Promise<void>;\n teardown?: () => Promise<void>;\n}\n\nexport interface TestCase {\n name: string;\n description: string;\n test: () => Promise<void>;\n timeout?: number;\n retries?: number;\n skip?: boolean;\n only?: boolean;\n}\n\nexport interface TestResult {\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: Error;\n screenshots?: string[];\n video?: string;\n trace?: string;\n}\n\nexport interface TestReport {\n suite: string;\n results: TestResult[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n };\n}\n\n// Test runner utilities\nexport class TestRunner {\n private config: TestConfig;\n private suites: TestSuite[] = [];\n\n constructor(config: TestConfig) {\n this.config = config;\n }\n\n addSuite(suite: TestSuite): void {\n this.suites.push(suite);\n }\n\n async runSuite(suiteName: string): Promise<TestReport> {\n const suite = this.suites.find(s => s.name === suiteName);\n if (!suite) {\n throw new Error(`Suite ${suiteName} not found`);\n }\n\n const results: TestResult[] = [];\n const startTime = Date.now();\n\n try {\n if (suite.setup) {\n await suite.setup();\n }\n\n for (const testCase of suite.tests) {\n if (testCase.skip) {\n results.push({\n name: testCase.name,\n status: 'skipped',\n duration: 0\n });\n continue;\n }\n\n const testStartTime = Date.now();\n try {\n await testCase.test();\n results.push({\n name: testCase.name,\n status: 'passed',\n duration: Date.now() - testStartTime\n });\n } catch (error) {\n results.push({\n name: testCase.name,\n status: 'failed',\n duration: Date.now() - testStartTime,\n error: error as Error\n });\n }\n }\n } finally {\n if (suite.teardown) {\n await suite.teardown();\n }\n }\n\n const summary = {\n total: results.length,\n passed: results.filter(r => r.status === 'passed').length,\n failed: results.filter(r => r.status === 'failed').length,\n skipped: results.filter(r => r.status === 'skipped').length,\n duration: Date.now() - startTime\n };\n\n return {\n suite: suiteName,\n results,\n summary\n };\n }\n\n async runAllSuites(): Promise<TestReport[]> {\n const reports: TestReport[] = [];\n \n for (const suite of this.suites) {\n const report = await this.runSuite(suite.name);\n reports.push(report);\n }\n\n return reports;\n }\n}\n\n// Test data generators\nexport class TestDataGenerator {\n static generateContent(type: string, overrides: any = {}): any {\n const base = {\n id: `test-${Date.now()}`,\n type,\n title: `Test ${type} Content`,\n slug: `test-${type}-content`,\n body: `Test content for ${type}`,\n author: {\n id: 'test-user',\n name: 'Test User',\n email: 'test@example.com'\n },\n status: 'draft',\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n\n static generateWorkflow(overrides: any = {}): any {\n const base = {\n id: `test-workflow-${Date.now()}`,\n name: 'Test Workflow',\n description: 'Test workflow for testing',\n stages: [\n {\n id: 'draft',\n name: 'Draft',\n order: 1,\n isPublishStage: false,\n allowsScheduling: false,\n permissions: ['content.edit']\n },\n {\n id: 'published',\n name: 'Published',\n order: 2,\n isPublishStage: true,\n allowsScheduling: true,\n permissions: ['content.publish']\n }\n ],\n transitions: [\n {\n id: 'draft-to-published',\n from: 'draft',\n to: 'published',\n permissions: ['content.publish']\n }\n ]\n };\n\n return { ...base, ...overrides };\n }\n\n static generateUser(role: string = 'user', overrides: any = {}): any {\n const base = {\n id: `test-user-${Date.now()}`,\n name: 'Test User',\n email: 'test@example.com',\n role,\n permissions: role === 'admin' ? ['*'] : ['content.view'],\n createdAt: new Date(),\n updatedAt: new Date()\n };\n\n return { ...base, ...overrides };\n }\n}\n\n// Test assertions\nexport class TestAssertions {\n static async expectElementVisible(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeVisible();\n }\n\n static async expectElementHidden(page: any, selector: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toBeHidden();\n }\n\n static async expectTextVisible(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeVisible();\n }\n\n static async expectTextHidden(page: any, text: string): Promise<void> {\n const element = await page.locator(`text=${text}`);\n await expect(element).toBeHidden();\n }\n\n static async expectElementCount(page: any, selector: string, count: number): Promise<void> {\n const elements = await page.locator(selector);\n await expect(elements).toHaveCount(count);\n }\n\n static async expectElementText(page: any, selector: string, text: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveText(text);\n }\n\n static async expectElementValue(page: any, selector: string, value: string): Promise<void> {\n const element = await page.locator(selector);\n await expect(element).toHaveValue(value);\n }\n}\n\n// Test helpers\nexport class TestHelpers {\n static async waitForElement(page: any, selector: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(selector, { timeout });\n }\n\n static async waitForText(page: any, text: string, timeout = 5000): Promise<void> {\n await page.waitForSelector(`text=${text}`, { timeout });\n }\n\n static async fillForm(page: any, formData: Record<string, string>): Promise<void> {\n for (const [field, value] of Object.entries(formData)) {\n await page.fill(`[name=\"${field}\"]`, value);\n }\n }\n\n static async clickButton(page: any, text: string): Promise<void> {\n await page.click(`button:has-text(\"${text}\")`);\n }\n\n static async clickLink(page: any, text: string): Promise<void> {\n await page.click(`a:has-text(\"${text}\")`);\n }\n\n static async takeScreenshot(page: any, name: string): Promise<void> {\n await page.screenshot({ path: `test-results/screenshots/${name}.png` });\n }\n\n static async measurePerformance(name: string, fn: () => Promise<void>): Promise<number> {\n const start = Date.now();\n await fn();\n const end = Date.now();\n console.log(`Performance: ${name} took ${end - start}ms`);\n return end - start;\n }\n}\n\n// Export default configuration\nexport const defaultTestConfig: TestConfig = {\n baseURL: 'http://localhost:3000',\n timeout: 30000,\n retries: 2,\n workers: 1,\n reporter: ['html', 'json'],\n browser: ['chromium', 'firefox', 'webkit'],\n mobile: true,\n tablet: true,\n desktop: true\n};\n"],"mappings":"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","names":["expect","expect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bernierllc/content-management-tests",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Comprehensive test suite for the content management system with Playwright, Jest, and integration tests",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@testing-library/user-event": "^14.5.0",
|
|
36
36
|
"jest-environment-jsdom": "^29.5.0",
|
|
37
37
|
"supertest": "^6.3.0",
|
|
38
|
-
"faker": "^
|
|
38
|
+
"@faker-js/faker": "^8.0.0",
|
|
39
39
|
"uuid": "^9.0.0",
|
|
40
40
|
"date-fns": "^2.30.0",
|
|
41
41
|
"lodash": "^4.17.21",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@bernierllc/content-autosave-manager": "1.0.1",
|
|
47
47
|
"@bernierllc/content-soft-delete": "1.0.0",
|
|
48
48
|
"@bernierllc/content-workflow-service": "0.1.1",
|
|
49
|
-
"@bernierllc/content-editor-service": "0.1.
|
|
49
|
+
"@bernierllc/content-editor-service": "0.1.2",
|
|
50
50
|
"@bernierllc/content-config-manager": "0.1.0",
|
|
51
51
|
"@bernierllc/content-editor-ui": "0.1.1",
|
|
52
52
|
"@bernierllc/content-workflow-ui": "0.1.1",
|
|
@@ -59,7 +59,6 @@
|
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/jest": "^29.5.0",
|
|
61
61
|
"@types/supertest": "^2.0.0",
|
|
62
|
-
"@types/faker": "^6.6.0",
|
|
63
62
|
"@types/uuid": "^9.0.0",
|
|
64
63
|
"@types/lodash": "^4.14.0",
|
|
65
64
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
@@ -74,32 +73,6 @@
|
|
|
74
73
|
"react": "^18.2.0",
|
|
75
74
|
"react-dom": "^18.2.0"
|
|
76
75
|
},
|
|
77
|
-
"jest": {
|
|
78
|
-
"testEnvironment": "jsdom",
|
|
79
|
-
"setupFilesAfterEnv": [
|
|
80
|
-
"<rootDir>/src/setup/jest.setup.ts"
|
|
81
|
-
],
|
|
82
|
-
"testMatch": [
|
|
83
|
-
"<rootDir>/src/**/*.test.ts",
|
|
84
|
-
"<rootDir>/src/**/*.test.tsx"
|
|
85
|
-
],
|
|
86
|
-
"collectCoverageFrom": [
|
|
87
|
-
"src/**/*.{ts,tsx}",
|
|
88
|
-
"!src/**/*.test.{ts,tsx}",
|
|
89
|
-
"!src/**/*.stories.{ts,tsx}",
|
|
90
|
-
"!src/setup/**",
|
|
91
|
-
"!src/fixtures/**",
|
|
92
|
-
"!src/mocks/**"
|
|
93
|
-
],
|
|
94
|
-
"coverageThreshold": {
|
|
95
|
-
"global": {
|
|
96
|
-
"branches": 80,
|
|
97
|
-
"functions": 80,
|
|
98
|
-
"lines": 80,
|
|
99
|
-
"statements": 80
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
76
|
"publishConfig": {
|
|
104
77
|
"access": "public",
|
|
105
78
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -108,6 +81,7 @@
|
|
|
108
81
|
"build": "tsup",
|
|
109
82
|
"dev": "tsup --watch",
|
|
110
83
|
"test": "jest",
|
|
84
|
+
"test:run": "jest --passWithNoTests",
|
|
111
85
|
"test:watch": "jest --watch",
|
|
112
86
|
"test:coverage": "jest --coverage",
|
|
113
87
|
"test:playwright": "playwright test",
|