RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/dotCMS/core

Cursor rule

.cursor/rules/e2e-rules.mdc
Cursor rules

Quality

89/100

Scores the file, not the repository.

Length

888 words

22 headings · 7 code blocks

Repository

949

— · pushed 0 days ago

Last changed

3 days ago

First indexed 3 days ago.
dotCMS/core/.cursor/rules/e2e-rules.mdcRawGitHub
1---
2globs: core-web/apps/dotcms-ui-e2e/**/*.spec.ts
3alwaysApply: false
4---
5 
6# Page Object Model (POM) Conventions for dotCMS E2E Tests
7 
8## Overview
9 
10This project follows the **Page Object Model (POM)** pattern for all E2E tests. This ensures maintainability, reusability, and clear separation of concerns.
11 
12## Directory Structure
13 
14```
15src/
16├── pages/ # Page Objects (one class per page)
17│ ├── login.page.ts
18│ ├── dashboard.page.ts
19│ └── content.page.ts
20├── components/ # Reusable UI components
21│ ├── sideMenu.component.ts
22│ ├── header.component.ts
23│ └── modal.component.ts
24├── tests/ # Test files that use Page Objects
25│ ├── login/
26│ ├── content/
27│ └── navigation/
28├── utils/ # Shared utilities and helpers
29│ └── utils.ts
30└── config/ # Configuration files
31 └── environments.ts
32```
33 
34## POM Rules
35 
36### 1. Page Objects
37 
38- **One class per page** - Each page has its own Page Object class
39- **Encapsulate all page interactions** - All `page.fill()`, `page.click()`, etc. should be in Page Objects
40- **Return meaningful data** - Methods should return relevant information when needed
41- **Handle environment differences** - Page Objects should adapt to different environments (dev/ci)
42- **ALWAYS use data-testid selectors** - Use `page.getByTestId()` instead of `page.locator()` with CSS selectors
43 
44### 2. Components
45 
46- **Reusable UI elements** - Components that appear across multiple pages
47- **Self-contained logic** - Each component manages its own state and interactions
48- **Composable** - Components can be used within Page Objects
49- **ALWAYS use data-testid selectors** - Use `page.getByTestId()` for all element interactions
50 
51### 3. Tests
52 
53- **Use Page Objects only** - Never interact directly with the DOM in tests
54- **Descriptive test names** - Clear, readable test descriptions
55- **One test per scenario** - Each test should verify one specific behavior
56- **Use test data files** - Centralize test data in separate files
57 
58## Selector Rules
59 
60### ✅ ALWAYS Use data-testid
61 
62```typescript
63// CORRECT - Use data-testid selectors
64await this.page.getByTestId("userNameInput").click();
65await this.page.getByTestId("userNameInput").fill(username);
66await this.page.getByTestId("password").fill(password);
67await this.page.getByTestId("submitButton").click();
68```
69 
70### ❌ NEVER Use CSS selectors
71 
72```typescript
73// WRONG - Don't use CSS selectors
74await this.page.locator('input[id="userId"]').fill(username);
75await this.page.locator('button[id="loginButton"]').click();
76await this.page.locator(".login-form input").fill(username);
77```
78 
79### Why data-testid?
80 
811. **More stable** - Not affected by CSS class changes or styling updates
822. **More specific** - Designed specifically for testing
833. **Better performance** - Playwright's `getByTestId()` is optimized
844. **Clearer intent** - Makes it obvious the element is for testing
85 
86## Code Examples
87 
88### ✅ Correct POM Implementation
89 
90```typescript
91// pages/login.page.ts
92export class LoginPage {
93 constructor(private page: Page) {}
94 
95 async login(username: string, password: string): Promise<void> {
96 const currentEnv = process.env["CURRENT_ENV"] || "dev";
97 const loginUrl =
98 currentEnv === "ci" ? "/login/" : "/dotAdmin/#/public/login";
99 
100 await this.page.goto(loginUrl);
101 await this.page.waitForLoadState();
102 
103 // Use data-testid selectors
104 await this.page.getByTestId("userNameInput").click();
105 await this.page.getByTestId("userNameInput").fill(username);
106 await this.page.getByTestId("userNameInput").press("Tab");
107 await this.page.getByTestId("password").fill(password);
108 await this.page.getByTestId("submitButton").click();
109 }
110 
111 async isLoggedIn(): Promise<boolean> {
112 const currentUrl = this.page.url();
113 return (
114 !currentUrl.includes("/login/") && !currentUrl.includes("/public/login")
115 );
116 }
117}
118 
119// tests/login/login.spec.ts
120test("User can login with valid credentials", async ({ page }) => {
121 const loginPage = new LoginPage(page);
122 
123 await loginPage.login("admin@dotcms.com", "admin");
124 
125 expect(await loginPage.isLoggedIn()).toBe(true);
126});
127```
128 
129### ❌ Incorrect Implementation
130 
131```typescript
132// DON'T DO THIS - Direct DOM interaction in tests
133test("User can login", async ({ page }) => {
134 await page.goto("/login/");
135 await page.fill('input[id="userId"]', "admin@dotcms.com");
136 await page.fill('input[id="password"]', "admin");
137 await page.click('button[id="loginButton"]');
138});
139 
140// DON'T DO THIS - Using CSS selectors in Page Objects
141export class LoginPage {
142 async login(username: string, password: string) {
143 await this.page.locator('input[id="userId"]').fill(username);
144 await this.page.locator('input[id="password"]').fill(password);
145 await this.page.locator('button[id="loginButton"]').click();
146 }
147}
148```
149 
150## Environment Handling
151 
152### Page Objects should handle environment differences:
153 
154```typescript
155export class LoginPage {
156 private getLoginUrl(): string {
157 const currentEnv = process.env["CURRENT_ENV"] || "dev";
158 return currentEnv === "ci" ? "/login/" : "/dotAdmin/#/public/login";
159 }
160}
161```
162 
163## Test Data Management
164 
165### Centralize test data:
166 
167```typescript
168// tests/login/credentialsData.ts
169export const validCredentials = [
170 { username: "admin@dotcms.com", password: "admin" },
171 { username: "test@dotcms.com", password: "test" },
172];
173 
174export const invalidCredentials = [
175 { username: "wrong@dotcms.com", password: "wrong" },
176];
177```
178 
179## Naming Conventions
180 
181- **Page Objects**: `[PageName].page.ts` (e.g., `login.page.ts`)
182- **Components**: `[ComponentName].component.ts` (e.g., `sideMenu.component.ts`)
183- **Test Files**: `[FeatureName].spec.ts` (e.g., `login.spec.ts`)
184- **Test Data**: `[FeatureName]Data.ts` (e.g., `credentialsData.ts`)
185 
186## Best Practices
187 
1881. **Keep Page Objects focused** - Each Page Object should handle one page only
1892. **Use meaningful method names** - `login()`, `navigateToContent()`, `verifyUserIsLoggedIn()`
1903. **Handle waits properly** - Use appropriate waits in Page Objects
1914. **Return useful data** - Methods should return information that tests need
1925. **Keep tests simple** - Tests should be easy to read and understand
1936. **Use TypeScript** - Leverage type safety for better maintainability
1947. **ALWAYS use data-testid** - Never use CSS selectors, always use `page.getByTestId()`
195 
196## Migration Guidelines
197 
198When migrating tests from Maven E2E:
199 
2001. **Identify pages** - Create Page Objects for each page
2012. **Extract components** - Identify reusable UI components
2023. **Centralize data** - Move test data to dedicated files
2034. **Update tests** - Refactor tests to use Page Objects
2045. **Handle environments** - Ensure Page Objects work in both dev and ci modes
2056. **Convert selectors** - Replace all CSS selectors with data-testid selectors
206 
207## Using Playwright Codegen
208 
209When using Playwright's codegen to generate tests:
210 
2111. **Run codegen**: `npx playwright codegen http://localhost:8080/dotAdmin/#/public/login`
2122. **Copy the generated selectors** - Use the `getByTestId()` calls from codegen
2133. **Update Page Objects** - Replace old selectors with the new data-testid selectors
2144. **Test the changes** - Verify the new selectors work correctly
215 
216---
217 
218**Remember**:
219 
220- Always use Page Objects for E2E tests
221- Never interact directly with the DOM in test files
222- ALWAYS use `data-testid` selectors with `page.getByTestId()`
223- Never use CSS selectors like `page.locator('input[id="..."]')`
224 

Commands it names

  • npx playwright codegen http://localhost:8080/dotAdmin/#/public/login

Sections

  • Page Object Model (POM) Conventions for dotCMS E2E Tests
  • Overview
  • Directory Structure
  • POM Rules
  • 1. Page Objects
  • 2. Components
  • 3. Tests
  • Selector Rules
  • ✅ ALWAYS Use data-testid
  • ❌ NEVER Use CSS selectors
  • Why data-testid?
  • Code Examples
  • ✅ Correct POM Implementation
  • ❌ Incorrect Implementation
  • Environment Handling
  • Page Objects should handle environment differences:
  • Test Data Management
  • Centralize test data:
  • Naming Conventions
  • Best Practices
  • Migration Guidelines
  • Using Playwright Codegen

What it covers

setuptestcode-stylearchitecturetesting-strategysecuritydatabaseuido-not

Stack — with the evidence

java

(1.00)

node

(1.00)

angular

(0.70)

jest

(0.70)

pytest

(0.70)

eslint

(0.70)

vercel

(0.70)

typescript

(0.60)

github-actions

(0.60)

javascript

(0.50)

python

(0.50)

Glob targeting

  • core-web/apps/dotcms-ui-e2e/**/*.spec.ts

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
dotCMS
Language
—
License
—
Archived
no

All configs in this repo

Also in dotCMS/core

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
dotCMS/core.github/copilot-instructions.md · 949Copilot instructionsjavanode+10setupbuildtestlint-format+1184/100today
dotCMS/corecore-web/apps/dotcms-ui-e2e/AGENTS.md · 949AGENTS.mdtypescriptjava+10setupstylearchtesting-strategy+278/1003 days ago
dotCMS/corecore-web/apps/mcp-server/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9setupbuildtestlint-format+589/1003 days ago
dotCMS/core.cursor/rules/doc-updates.mdc · 949Cursor rulesjavanode+9docs30/1003 days ago
dotCMS/core.cursor/rules/dotcms-guide.mdc · 949Cursor rulesjavanode+9archdo-notdocs69/1003 days ago
dotCMS/core.cursor/rules/frontend-context.mdc · 949Cursor rulesjavanode+10teststyledocs78/1003 days ago
dotCMS/core.cursor/rules/java-context.mdc · 949Cursor rulesjavanode+9buildstyle44/1003 days ago
dotCMS/core.cursor/rules/test-context.mdc · 949Cursor rulesjavanode+9testtesting-strategy54/1003 days ago
dotCMS/core.github/instructions/frontend.instructions.md · 949Copilot instructionsjavanode+10testlint-formatstylearch+369/1003 days ago
dotCMS/coreCLAUDE.md · 949CLAUDE.mdjavanode+9setupbuildteststyle+799/100today
dotCMS/corecore-web/AGENTS.md · 949AGENTS.mdjavanode+13style63/1003 days ago
dotCMS/corecore-web/CLAUDE.md · 949CLAUDE.mdjavanode+13teststylearchtesting-strategy+3100/1003 days ago
dotCMS/corecore-web/apps/dotcms-ui/AGENTS.md · 949AGENTS.mdtypescriptjava+9buildteststyledependencies+394/1003 days ago
dotCMS/corecore-web/libs/block-editor/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9archdo-not69/1003 days ago
dotCMS/corecore-web/libs/new-block-editor/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9lint-formatstyledo-notagent-behaviour61/1003 days ago
dotCMS/corecore-web/libs/portlets/CLAUDE.md · 949CLAUDE.mdjavanode+9setupteststyleui+177/1003 days ago
dotCMS/corecore-web/libs/portlets/edit-ema/portlet/src/lib/store/CLAUDE.md · 949CLAUDE.mdjavanode+9teststylearchtypes+265/1003 days ago
dotCMS/corecore-web/libs/sdk/client/CLAUDE.md · 949CLAUDE.mdtypescriptjava+9setupbuildtestlint-format+997/1003 days ago
dotCMS/corecore-web/libs/sdk/react/CLAUDE.md · 949CLAUDE.mdtypescriptjava+10setupbuildtestlint-format+997/1003 days ago
dotCMS/coredotCMS/src/main/java/com/dotcms/rest/CLAUDE.md · 949CLAUDE.mdjavanode+9typesdatabaseapido-not+157/1003 days ago
Diff against .github/copilot-instructions.md Diff against core-web/apps/dotcms-ui-e2e/AGENTS.md Diff against core-web/apps/mcp-server/CLAUDE.md Diff against .cursor/rules/doc-updates.mdc Diff against .cursor/rules/dotcms-guide.mdc Diff against .cursor/rules/frontend-context.mdc Diff against .cursor/rules/java-context.mdc Diff against .cursor/rules/test-context.mdc Diff against .github/instructions/frontend.instructions.md Diff against CLAUDE.md Diff against core-web/AGENTS.md Diff against core-web/CLAUDE.md Diff against core-web/apps/dotcms-ui/AGENTS.md Diff against core-web/libs/block-editor/CLAUDE.md Diff against core-web/libs/new-block-editor/CLAUDE.md Diff against core-web/libs/portlets/CLAUDE.md Diff against core-web/libs/portlets/edit-ema/portlet/src/lib/store/CLAUDE.md Diff against core-web/libs/sdk/client/CLAUDE.md Diff against core-web/libs/sdk/react/CLAUDE.md Diff against dotCMS/src/main/java/com/dotcms/rest/CLAUDE.md

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126Cursor rulesgobun+5setupbuildtestlint-format+6100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45Cursor rulestypescriptpytest+15teststyletesting-strategysecurity+397/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack