Skip to content

Commit 2c5b288

Browse files
authored
Merge pull request #15 from ivangrynenko/feature/changelog-and-commands
Add slash command installation flow
2 parents 4ec65b7 + eac2b95 commit 2c5b288

29 files changed

+4261
-194
lines changed

.cursor/commands/behat-drevops.md

Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
# Custom Command: Behat DrevOps
2+
3+
## Command Usage
4+
`/behat-drevops <task>`
5+
6+
Treat `<task>` as the description of the Behat scenario the user wants. The remainder of this guide explains how to fulfil that request.
7+
8+
## Role definition
9+
10+
You are behat test writer, implement the test requested as {$ARGUMENT}
11+
12+
### DrevOps Behat Steps Integration
13+
For Drupal projects using the `drevops/behat-steps` library, which provides comprehensive Behat step definitions. When available in `vendor/drevops/behat-steps/`, use these pre-built steps.
14+
15+
### Available Behat Traits from DrevOps
16+
When writing custom Behat tests, check for these available traits:
17+
18+
#### Common Traits
19+
- `ContentTrait` - Content management steps
20+
- `FieldTrait` - Field interaction steps
21+
- `FileTrait` - File handling steps
22+
- `PathTrait` - Path navigation steps
23+
- `SearchApiTrait` - Search API testing steps
24+
- `TaxonomyTrait` - Taxonomy term steps
25+
- `WaitTrait` - Wait conditions steps
26+
- `WatchdogTrait` - Watchdog/logging steps
27+
28+
#### Additional Available Traits
29+
- `BigPipeTrait` - BigPipe functionality testing
30+
- `BlockContentTrait` - Block content management
31+
- `BlockTrait` - Block placement and configuration
32+
- `CookieTrait` - Cookie manipulation
33+
- `DateTrait` - Date field handling
34+
- `DraggableViewsTrait` - Draggable views testing
35+
- `EckTrait` - Entity Construction Kit support
36+
- `ElementTrait` - DOM element interactions
37+
- `EmailTrait` - Email testing capabilities
38+
- `FileDownloadTrait` - File download verification
39+
- `JsTrait` - JavaScript execution
40+
- `KeyboardTrait` - Keyboard interaction
41+
- `LinkTrait` - Link verification
42+
- `MediaTrait` - Media entity handling
43+
- `MenuTrait` - Menu system testing
44+
- `MetaTagTrait` - Meta tag verification
45+
- `OverrideTrait` - Override functionality
46+
- `ParagraphsTrait` - Paragraphs field testing
47+
- `ResponseTrait` - HTTP response assertions
48+
- `RoleTrait` - User role management
49+
- `SelectTrait` - Select field interactions
50+
- `TestmodeTrait` - Test mode utilities
51+
- `UserTrait` - User management
52+
- `VisibilityTrait` - Element visibility checks
53+
- `WysiwygTrait` - WYSIWYG editor testing
54+
55+
### Writing Behat Tests - Best Practices
56+
57+
#### 1. Step Format Guidelines
58+
```gherkin
59+
# Use descriptive placeholder names
60+
Given I am viewing the "About Us" page content
61+
When I fill in "Title" with "New Page Title"
62+
Then I should see the text "Successfully created"
63+
64+
# Use "the following" for table data
65+
When I create nodes with the following details:
66+
| title | type | status |
67+
| About Page | page | 1 |
68+
| Contact Page | page | 1 |
69+
70+
# Use "with" for properties
71+
Given I am logged in as a user with the "administrator" role
72+
```
73+
74+
#### User Authentication in Behat Tests
75+
76+
**Important**: When creating users in Behat tests, follow these guidelines:
77+
78+
1. **Always include password field** when creating users:
79+
```gherkin
80+
Given users:
81+
| name | mail | pass | roles |
82+
| admin_user | admin@example.com | password | administrator |
83+
| editor_user | editor@example.com | password | content_editor |
84+
| basic_user | user@example.com | password | |
85+
```
86+
87+
2. **Never manually assign "authenticated" role**:
88+
- ❌ Wrong: `| basic_user | user@example.com | password | authenticated |`
89+
- ✅ Correct: `| basic_user | user@example.com | password | |`
90+
- The "authenticated" role is automatically assigned by Drupal
91+
92+
3. **Common user creation patterns**:
93+
```gherkin
94+
# Background section for multiple scenarios
95+
Background:
96+
Given users:
97+
| name | mail | pass | roles |
98+
| site_admin_user | site_admin@example.com | password | civictheme_site_administrator |
99+
| content_editor_user | editor@example.com | password | civictheme_content_author |
100+
| no_role_user | basic@example.com | password | |
101+
102+
# Using the created users
103+
Scenario: Admin can access restricted pages
104+
Given I am logged in as "site_admin_user"
105+
When I go to "/admin/structure"
106+
Then I should not see "Access denied"
107+
```
108+
109+
4. **Login methods**:
110+
```gherkin
111+
# Login as created user
112+
Given I am logged in as "username_from_table"
113+
114+
# Login with role
115+
Given I am logged in as a user with the "administrator" role
116+
117+
# Anonymous user
118+
Given I am an anonymous user
119+
```
120+
121+
#### 2. Step Type Conventions
122+
123+
**Given Steps** (Prerequisites):
124+
```gherkin
125+
Given I am logged in as a user with the "administrator" role
126+
Given "page" content exists with the title "Home Page"
127+
Given I have a "article" content type
128+
```
129+
130+
**When Steps** (Actions):
131+
```gherkin
132+
When I visit "node/add/page"
133+
When I fill in "Title" with "Test Page"
134+
When I press "Save"
135+
When I click "Add content"
136+
```
137+
138+
**Then Steps** (Assertions):
139+
```gherkin
140+
Then I should see the text "Page created"
141+
Then I should not see "Access denied"
142+
Then the response status code should be 200
143+
Then the "Title" field should contain "Test Page"
144+
```
145+
146+
### Running Behat Tests
147+
148+
```bash
149+
# Run all Behat tests
150+
ahoy test-behat
151+
152+
# Run specific feature
153+
ahoy test-behat tests/behat/features/content.feature
154+
155+
# Run tests with specific tag
156+
ahoy test-behat --tags=@api
157+
158+
# Run tests excluding a tag
159+
ahoy test-behat --tags='~@skipped'
160+
161+
# Run with specific profile
162+
ahoy test-behat -p p0
163+
```
164+
165+
### Debugging Behat Tests
166+
167+
1. **Add Screenshots**:
168+
```gherkin
169+
Then save screenshot
170+
# Screenshots saved to .logs/screenshots/
171+
```
172+
173+
2. **Pause Execution**:
174+
```gherkin
175+
Then I break
176+
# Pauses test execution for debugging
177+
```
178+
179+
3. **Check Element Visibility**:
180+
```gherkin
181+
Then I wait for the "#edit-title" element to appear
182+
Then I wait 5 seconds for the ".banner" element to appear
183+
```
184+
185+
4. **Debug JavaScript**:
186+
```gherkin
187+
Then I execute javascript "console.log(jQuery('.tabs').length)"
188+
```
189+
190+
### Behat Configuration Notes
191+
192+
Common `behat.yml` configuration includes:
193+
- Screenshot capture on failure
194+
- JUnit output for CI integration
195+
- Parallel testing profiles
196+
- Chrome/Selenium integration for JavaScript tests
197+
198+
### Adding Custom Behat Steps
199+
200+
When you need custom steps not provided by DrevOps Behat Steps:
201+
202+
1. Add to `tests/behat/bootstrap/FeatureContext.php`
203+
2. Follow existing patterns in the file
204+
3. Use proper PHPDoc annotations
205+
4. Include proper error handling
206+
207+
Example:
208+
```php
209+
/**
210+
* Verifies custom element is displayed.
211+
*
212+
* @Then I should see the custom element
213+
*/
214+
public function iShouldSeeTheCustomElement(): void {
215+
$element = $this->getSession()->getPage()->find('css', '.custom-element');
216+
if (!$element || !$element->isVisible()) {
217+
throw new \Exception('Custom element is not visible');
218+
}
219+
}
220+
```
221+
222+
### Common Behat Issues and Solutions
223+
224+
#### 1. WYSIWYG/CKEditor Fields
225+
When testing forms with WYSIWYG editors (like CKEditor):
226+
227+
**Problem**: Standard field filling doesn't work with CKEditor fields
228+
```gherkin
229+
# This may fail:
230+
And I fill in "Body" with "Content text"
231+
```
232+
233+
**Solution**: Use the WysiwygTrait from DrevOps
234+
```php
235+
// In FeatureContext.php, add:
236+
use DrevOps\BehatSteps\WysiwygTrait;
237+
238+
class FeatureContext extends DrupalContext {
239+
use WysiwygTrait;
240+
// ... other traits
241+
}
242+
```
243+
244+
Then use the WYSIWYG-specific step:
245+
```gherkin
246+
And I fill in WYSIWYG "Body" with "This content will be properly filled in CKEditor"
247+
```
248+
249+
#### 2. Multi-Domain Sites
250+
For sites with multiple domains (like WorkSafe/Consumer Protection):
251+
252+
**Problem**: Domain selection uses radio buttons, not checkboxes
253+
```gherkin
254+
# Wrong:
255+
And I check "WorkSafe"
256+
257+
# Correct:
258+
And I select the radio button "WorkSafe"
259+
```
260+
261+
#### 3. Media Bundle Names
262+
When creating media entities, use the correct bundle names:
263+
264+
**Problem**: Generic bundle names may not exist
265+
```gherkin
266+
# This may fail:
267+
Given media:
268+
| name | bundle |
269+
| test-doc.pdf | document |
270+
```
271+
272+
**Solution**: Use the actual bundle name from your site
273+
```gherkin
274+
Given media:
275+
| name | bundle |
276+
| test-doc.pdf | civictheme_document |
277+
```
278+
279+
#### 4. File System Configuration
280+
For sites with private file system:
281+
282+
**Problem**: Creating files with public:// when system uses private://
283+
```gherkin
284+
# May fail if system is configured for private files:
285+
Given files:
286+
| uri |
287+
| public://test-doc.pdf |
288+
```
289+
290+
**Solution**: Use private:// URI scheme
291+
```gherkin
292+
Given files:
293+
| uri |
294+
| private://test-doc.pdf |
295+
```
296+
297+
#### 5. Testing Without Form Submission
298+
When form submission fails, break down the test:
299+
300+
```gherkin
301+
# Instead of one large scenario, split into:
302+
Scenario: Verify form fields exist
303+
Then I should see the field "Title"
304+
And I should see the field "Body"
305+
306+
Scenario: Test form submission
307+
When I fill in "Title" with "Test"
308+
And I fill in WYSIWYG "Body" with "Content"
309+
And I press "Save"
310+
Then I should see "has been created"
311+
```
312+
313+
#### 6. Conditional Steps for Flexible Tests
314+
Add conditional steps in FeatureContext.php for more resilient tests:
315+
316+
```php
317+
/**
318+
* Click on the first matching element if it exists.
319+
*
320+
* @When I click on the first :selector element if it exists
321+
*/
322+
public function iClickOnTheFirstElementIfItExists($selector): void {
323+
$elements = $this->getSession()->getPage()->findAll('css', $selector);
324+
325+
// If no elements exist, that's okay - just skip
326+
if (empty($elements)) {
327+
return;
328+
}
329+
330+
// Click the first element
331+
$elements[0]->click();
332+
}
333+
```
334+
335+
Use in tests:
336+
```gherkin
337+
# Won't fail if no publications exist yet
338+
When I click on the first ".ct-list__content a" element if it exists
339+
```
340+
341+
#### 7. URL Patterns and Path Aliases
342+
Be aware that Drupal may use path aliases:
343+
344+
```gherkin
345+
# Instead of assuming /node/123 format:
346+
And the url should match "\/node\/\d+"
347+
348+
# Check for the actual alias pattern:
349+
And the url should match "\/publications\/[\w-]+"
350+
```
351+
352+
#### 8. Status Code Checks with JavaScript Drivers
353+
Status code assertions don't work with Selenium/JavaScript drivers:
354+
355+
```gherkin
356+
# This will fail with Selenium:
357+
Then the response status code should be 200
358+
359+
# Use content-based verification instead:
360+
Then I should see "Expected page content"
361+
And I should not see "Access denied"
362+
```
363+
364+
#### 9. Running Specific Scenarios
365+
To run a single scenario during development:
366+
```bash
367+
# Run scenario starting at line 33
368+
docker compose exec cli vendor/bin/behat tests/behat/features/file.feature:33
369+
```
370+
371+
#### 10. Debugging Failed Tests
372+
Always check screenshots when tests fail:
373+
```bash
374+
# Check latest screenshots
375+
ls -la .logs/screenshots/ | tail -5
376+
377+
# Use Playwright to view screenshots
378+
mcp__playwright__browser_navigate with file:// URL

0 commit comments

Comments
 (0)