201 lines
4.7 KiB
Markdown
201 lines
4.7 KiB
Markdown
# Data-TestID Pattern Rules
|
|
|
|
**Purpose**: Universal rules that survive code changes
|
|
**Based On**: Automation test requirements + existing code patterns
|
|
**Verification**: Pattern-based (not file-specific)
|
|
|
|
---
|
|
|
|
## 🎯 CORE PATTERN
|
|
|
|
```
|
|
{scope}__{element_name}
|
|
```
|
|
|
|
### Rules:
|
|
1. **Double underscore (`__`)** separates scope from element name
|
|
2. **Single underscore (`_`)** within element names for readability
|
|
3. **All lowercase** - no camelCase, no PascalCase
|
|
4. **Snake_case** throughout
|
|
|
|
---
|
|
|
|
## 📋 SCOPE DEFINITIONS
|
|
|
|
| Scope | Purpose | Example Files |
|
|
|-------|---------|---------------|
|
|
| `student_login` | Student login page | SignInPage.jsx |
|
|
| `student_nav` | Student navigation header | Design1Header.jsx |
|
|
| `mandatory_reset` | Mandatory password reset modal | MandatoryPasswordResetModal.jsx |
|
|
| `profile_incomplete` | Profile incomplete modal | ProfileIncompleteModal.jsx |
|
|
| `profile_editor` | Profile editor form | StudentProfileEditor.jsx |
|
|
| `dashboard` | Dashboard page | DashboardPage.jsx |
|
|
| `assessment_card` | Assessment card component | ProductCard.jsx |
|
|
|
|
---
|
|
|
|
## 🔤 ELEMENT NAME PATTERNS
|
|
|
|
### Input Fields
|
|
```
|
|
{scope}__{field_name}_input
|
|
```
|
|
**Examples:**
|
|
- `student_login__identifier_input`
|
|
- `profile_editor__first_name_input`
|
|
- `mandatory_reset__current_password_input`
|
|
|
|
### Select/Dropdown
|
|
```
|
|
{scope}__{field_name}_select
|
|
```
|
|
**Examples:**
|
|
- `profile_editor__gender_select`
|
|
- `profile_editor__board_stream_select`
|
|
|
|
### Textarea
|
|
```
|
|
{scope}__{field_name}_textarea
|
|
```
|
|
**Examples:**
|
|
- `profile_editor__specially_abled_details_textarea`
|
|
- `profile_editor__achievement_academics_textarea`
|
|
|
|
### Checkbox
|
|
```
|
|
{scope}__{field_name}_checkbox
|
|
```
|
|
**Examples:**
|
|
- `student_login__remember_checkbox`
|
|
- `profile_editor__specially_abled_checkbox`
|
|
|
|
### Buttons
|
|
```
|
|
{scope}__{action}_button
|
|
```
|
|
**Examples:**
|
|
- `student_login__submit_button`
|
|
- `profile_editor__save_button`
|
|
- `profile_editor__prev_button`
|
|
- `profile_editor__next_button`
|
|
- `profile_editor__cancel_button`
|
|
|
|
### Links
|
|
```
|
|
{scope}__{destination}_link
|
|
```
|
|
**Examples:**
|
|
- `student_nav__dashboard_link`
|
|
- `student_nav__assessments_link`
|
|
|
|
### Modals/Containers
|
|
```
|
|
{scope}__modal
|
|
{scope}__form
|
|
{scope}__dropdown
|
|
```
|
|
**Examples:**
|
|
- `mandatory_reset__modal`
|
|
- `student_login__form`
|
|
- `student_nav__profile_dropdown`
|
|
|
|
### Error Messages
|
|
```
|
|
{scope}__{field_name}_error
|
|
{scope}__error_banner
|
|
{scope}__error_toast
|
|
```
|
|
**Examples:**
|
|
- `mandatory_reset__current_password_error`
|
|
- `student_login__error_banner`
|
|
- `student_login__error_toast`
|
|
|
|
### Progress/Status
|
|
```
|
|
{scope}__progress_value
|
|
```
|
|
**Examples:**
|
|
- `profile_editor__progress_value`
|
|
- `profile_incomplete__progress_value`
|
|
|
|
---
|
|
|
|
## 🔄 DYNAMIC PATTERNS
|
|
|
|
### Dynamic Collections (Checkboxes, Cards)
|
|
```
|
|
{scope}__{base_name}__{formatted_value}
|
|
```
|
|
|
|
**Formatting Function** (if needed):
|
|
```javascript
|
|
const formatTestId = (text) => {
|
|
return text
|
|
.toLowerCase()
|
|
.replace(/^\d+\.\s*/, '') // Remove leading number and dot
|
|
.replace(/\s+/g, '_') // Replace spaces with underscores
|
|
.replace(/[^a-z0-9_]/g, '') // Remove special characters
|
|
}
|
|
```
|
|
|
|
**Examples:**
|
|
- `profile_editor__short_term_focus__academics` (from "01. Academics")
|
|
- `profile_editor__club__science_club` (from "1. Science Club")
|
|
- `assessment_card__{assignmentId}` (dynamic ID)
|
|
- `assessment_card__{assignmentId}__action` (dynamic action button)
|
|
|
|
### Tab Navigation
|
|
```
|
|
{scope}__tab_{formatted_tab_name}
|
|
```
|
|
**Examples:**
|
|
- `profile_editor__tab_personal_information`
|
|
- `profile_editor__tab_contact_information`
|
|
|
|
---
|
|
|
|
## ⚠️ CRITICAL RULES
|
|
|
|
1. **NEVER use single underscore between scope and element**
|
|
- ❌ `student_login_identifier_input`
|
|
- ✅ `student_login__identifier_input`
|
|
|
|
2. **NEVER use camelCase or PascalCase**
|
|
- ❌ `studentLogin__identifierInput`
|
|
- ❌ `StudentLogin__IdentifierInput`
|
|
- ✅ `student_login__identifier_input`
|
|
|
|
3. **NEVER use hyphens**
|
|
- ❌ `student-login__identifier-input`
|
|
- ✅ `student_login__identifier_input`
|
|
|
|
4. **ALWAYS use descriptive element names**
|
|
- ❌ `profile_editor__btn1`
|
|
- ✅ `profile_editor__save_button`
|
|
|
|
5. **For dynamic values, use double underscore before dynamic part**
|
|
- ✅ `profile_editor__short_term_focus__academics`
|
|
- ❌ `profile_editor__short_term_focus_academics`
|
|
|
|
---
|
|
|
|
## ✅ VERIFICATION PATTERN
|
|
|
|
All attributes must match this regex:
|
|
```regex
|
|
^[a-z][a-z0-9_]*__[a-z][a-z0-9_]*(__[a-z0-9_]+)*$
|
|
```
|
|
|
|
**Breakdown:**
|
|
- `^[a-z][a-z0-9_]*` - Scope (starts with lowercase letter)
|
|
- `__` - Double underscore separator
|
|
- `[a-z][a-z0-9_]*` - Element name (starts with lowercase letter)
|
|
- `(__[a-z0-9_]+)*` - Optional dynamic parts (each prefixed with `__`)
|
|
|
|
---
|
|
|
|
**Note**: These rules are universal and apply to ALL future implementations, regardless of code changes.
|
|
|
|
|
|
|