From db3fcb4101eb9d1eb5cf4c640a1f073a2baab6f0 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Fri, 10 Apr 2026 20:20:32 +1000 Subject: [PATCH] [#625] Removed unmaintained 2.x to 3.x migration information. --- .gitattributes | 1 - CLAUDE.md | 1 - MIGRATION.md | 214 ------------------------------------------------- README.md | 177 ---------------------------------------- 4 files changed, 393 deletions(-) delete mode 100644 MIGRATION.md diff --git a/.gitattributes b/.gitattributes index f72b1add..8aa15e60 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,7 +9,6 @@ /.gitignore export-ignore /CLAUDE.md export-ignore /CONTRIBUTING.md export-ignore -/MIGRATION.md export-ignore /behat.yml export-ignore /docker-compose.yml export-ignore /docs.php export-ignore diff --git a/CLAUDE.md b/CLAUDE.md index 743ba50e..81ccae62 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,7 +98,6 @@ Example: To skip `beforeScenario` hook from `ElementTrait`, add `@behat-steps-sk ## Documentation - List of all available steps is produced from trait and method comments and exported into [STEPS.md](STEPS.md) -- Migration guide for upgrading from 2.x: [MIGRATION.md](MIGRATION.md) ### Updating Steps Documentation The [STEPS.md](STEPS.md) documentation is automatically generated from the source code using the [docs.php](docs.php) file. After making changes to step definitions or adding new ones, you should regenerate the documentation: diff --git a/MIGRATION.md b/MIGRATION.md deleted file mode 100644 index 4a802ec6..00000000 --- a/MIGRATION.md +++ /dev/null @@ -1,214 +0,0 @@ -# Migration - -A migration map of the step definitions available in v2 to v3. - -| V2 | V3 | -|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **`BlockTrait`** | **`Drupal\BlockTrait`** | -| `When I create a block of type :label with:` | `Given the instance of :admin_label block exists with the following configuration:` | -| `When I configure the block with the label :label with:` | `Given the block :label has the following configuration:` | -| `When I configure a visibility condition :condition for the block with label :label` | `Given the block :label has the following :condition condition configuration:` | -| `When I remove the visibility condition :condition from the block with label :label` | `Given the block :label has the :condition condition removed` | -| `When I enable the block with label :label` | `Given the block :label is enabled` | -| `When I disable the block with label :label` | `Given the block :label is disabled` | -| `Then block with label :label should exist` | `Then the block :label should exist` | -| `Then block with label :label should not exist` | `Then the block :label should not exist` | -| `When block with label :label should exist in the region :region` | `Then the block :label should exist in the :region region` | -| `When block with label :label should not exist in the region :region` | `Then the block :label should not exist in the :region region` | -| `Then the block with label :label should have the visibility condition :condition` | `REMOVED` | -| `Then the block with label :label should not have the visibility condition :condition` | `REMOVED` | -|   | | -| **`ContentBlockTrait`** | **`Drupal\ContentBlockTrait`** | -| `Given :type block_content type exists` | `Then the content block type :type should exist` | -| `Given no :type block_content:` | `Given the following :type content blocks do not exist:` | -| `When I edit :type block_content_type with description :description` | `When I edit the :type content block with the description :description` | -| `Given :type block_content:` | `Given the following :type content blocks exist:` | -|   | | -| **`ContentTrait`** | **`Drupal\ContentTrait`** | -| `Given no :type content type` | `Given the content type :content_type does not exist` | -| `Given no ([a-zA-z0-9_-]+) content:$/` | `Given the following :content_type content does not exist:` | -| `When I visit :type :title` | `When I visit the :content_type content page with the title :title` | -| `When I edit :type :title` | `When I visit the :content_type content edit page with the title :title` | -| `When I delete :type :title` | `When I visit the :content_type content delete page with the title :title` | -| `When the moderation state of :type :title changes from :old_state to :new_state` | `When I change the moderation state of the :content_type content with the title :title to the :new_state state` | -| `When I visit :type :title scheduled transitions` | `When I visit the scheduled transitions page of the :content_type content with the title :title` | -|   | | -| **`CookieTrait`** | **`CookieTrait`** | -| `Then a cookie with( the) name :name should exist` | `Then a cookie with the name :name should exist` | -| `Then a cookie with( the) name :name and value :value should exist` | `Then a cookie with the name :name and the value :value should exist` | -| `Then a cookie with( the) name :name and value containing :partial_value should exist` | `Then a cookie with the name :name and a value containing :partial_value should exist` | -| `Then a cookie with( the) name containing :partial_name should exist` | `Then a cookie with a name containing :partial_name should exist` | -| `Then a cookie with( the) name containing :partial_name and value :value should exist` | `Then a cookie with a name containing :partial_name and the value :value should exist` | -| `Then a cookie with( the) name containing :partial_name and value containing :partial_value should exist` | `Then a cookie with a name containing :partial_name and a value containing :partial_value should exist` | -| `Then a cookie with( the) name :name should not exist` | `Then a cookie with the name :name should not exist` | -| `Then a cookie with( the) name :name and value :value should not exist` | `Then a cookie with the name :name and the value :value should not exist` | -| `Then a cookie with( the) name :name and value containing :partial_value should not exist` | `Then a cookie with the name :name and a value containing :partial_value should not exist` | -| `Then a cookie with( the) name containing :partial_name should not exist` | `Then a cookie with a name containing :partial_name should not exist` | -| `Then a cookie with( the) name containing :partial_name and value :value should not exist` | `Then a cookie with a name containing :partial_name and the value :value should not exist` | -| `Then a cookie with( the) name containing :partial_name and value containing :partial_value should not exist` | `Then a cookie with a name containing :partial_name and a value containing :partial_value should not exist` | -|   | | -| **`DraggableviewsTrait`** | **`Drupal\DraggableviewsTrait`** | -| `Then I save draggable views :view_id view :views_display_id display :bundle items in the following order:` | `When I save the draggable views items of the view :view_id and the display :views_display_id for the :bundle content in the following order:` | -|   | | -| **`EckTrait`** | **`Drupal\EckTrait`** | -| `Given :bundle :entity_type entities:` | `Given the following eck :bundle :entity_type entities exist:` | -| `Given no :bundle :entity_type entities:` | `Given the following eck :bundle :entity_type entities do not exist:` | -| `When I edit :bundle :entity_type with title :label` | `When I edit eck :bundle :entity_type entity with the title :title` | -| `When I visit :bundle :entity_type with title :label` | `When I visit eck :bundle :entity_type entity with the title :title` | -|   | | -| **`ElementTrait`** | **`ElementTrait`** | -| `Then I( should) see the :selector element with the :attribute attribute set to :value` | `Then the element :selector with the attribute :attribute and the value :value should exist` | -| `I( should) see the :selector element with a(n) :attribute attribute containing :value` | `Then the element :selector with the attribute :attribute and the value containing :value should exist` | -| `Then I should see an element :selector using :type contains :text text` | Removed. Use `Then /^the "(?P[^"]*)" element should contain "(?P(?:[^"]\|\\")*)"$/` instead. | -|   | | -| **`EmailTrait`** | **`Drupal\EmailTrait`** | -| `Given I enable the test email system` | `When I enable the test email system` | -| `Given I disable the test email system` | `When I disable the test email system` | -| `Then an email is sent to :address` | `Then an email should be sent to the :address` | -| `Then no emails were sent` | `Then no emails should have been sent` | -| `Then no emails were sent to :address` | `Then no emails should have been sent to the :address` | -| `Then an email header :header contains:` | `Then the email header :header should contain:` | -| `Then an email header :header contains exact:` | `Then the email header :header should exactly be:` | -| `Then /^an email to "(?P[^"]*)" user is "(?P[^"]*)" with "(?P[^"]*)" content:$/` | `Then an email should be sent to the address :address with the content:` | -| `NEW` | `Then an email should be sent to the address :address with the content containing:` | -| `NEW` | `Then an email should be sent to the address :address with the content not containing:` | -| `NEW` | `Then an email should not be sent to the address :address with the content:` | -| `NEW` | `Then an email should not be sent to the address :address with the content containing:` | -| `Then an email :field contains` | `Then the email field :field should contain:` | -| `Then an email :field contains exact` | `Then the email field :field should be:` | -| `Then an email :field does not contain` | `Then the email field :field should not contain:` | -| `Then an email :field does not contains exact` | `Then the email field :field should not be:` | -| `When I follow the link number :number in the email with the subject` | `When I follow link number :link_number in the email with the subject :subject` | -| `NEW` | `When I follow link number :link_number in the email with the subject containing :subject` | -| `Then file :name attached to the email with the subject` | `Then the file :file_name should be attached to the email with the subject :subject` | -| `NEW` | `Then the file :file_name should be attached to the email with the subject containing :subject` | -|   | | -| **`FieldTrait`** | **`FieldTrait`** | -| `Then I see field :name` | `Then the field :name should exist` | -| `Then I don't see field :name` | `Then the field :name should not exist` | -| `Then field :name :exists on the page` | `REMOVED` | -| `Then field :name should be :presence on the page and have state :state` | `REMOVED` | -| `Then field :name is :disabled on the page` | `Then the field :name should have :enabled_or_disabled state` | -| `Then I fill color in :field for :value` | `When I fill in the color field :field with the value :value` | -| `Then color field :field value is :value` | `Then the color field :field should have the value :value` | -| `Then fill in WYSIWYG :field with :value` | `When I fill in the WYSIWYG field :field with the :value` | -|   -| **`FileDownloadTrait`** | **`FileDownloadTrait`** | -| `Then I download file from :url` | `When I download the file from the URL :url` | -| `Then I download file from link :link` | `When I download the file from the link :link` | -| `Then I see download :link link :presence(on the page)` | `REMOVED` | -| `Then downloaded file contains:` | `Then the downloaded file should contain:` | -| `Then downloaded file name is :name` | `Then the downloaded file name should be :name` | -| `NEW` | `Then the downloaded file name should contain :name` | -| `Then downloaded file is zip archive that contains files:` | `Then the downloaded file should be a zip archive containing the files named:` | -| `NEW` | `Then the downloaded file should be a zip archive containing the files partially named:` | -|   -| **`FileTrait`** | **`Drupal\FileTrait`** | -| `Given managed file:` | `Given the following managed files:` | -| `Given no managed files:` | `Given the following managed files do not exist:` | -| `Given unmanaged file :uri created` | `Given the unmanaged file at the URI :uri exists` | -| `Given unmanaged file :uri created with content :content` | `Given the unmanaged file at the URI :uri exists with content:` | -| `Then unmanaged file :uri exists` | `Then an unmanaged file at the URI :uri should exist` | -| `Then unmanaged file :uri does not exist` | `Then an unmanaged file at the URI :uri should not exist` | -| `Then unmanaged file :uri has content :content` | `Then an unmanaged file at the URI :uri should contain :content` | -| `Then unmanaged file :uri does not have content :content` | `Then an unmanaged file at the URI :uri should not contain :content` | -|   -| **`JsTrait`** | **`ElementTrait`** | -| `When I accept confirmation dialogs` | `Given I accept all confirmation dialogs` | -| `When I do not accept confirmation dialogs` | `Given I do not accept any confirmation dialogs` | -| `When /^(?:I)click (an?\|on) "(?P[^"]*)" element$/` | `When I click on the element :selector` | -| `When I trigger JS :event event on :selector element` | `When I trigger the JS event :event on the element :selector` | -| `Then /^I scroll to an? element with id "([^"]*)"$/` | `When I scroll to the element :selector` | -| `Then the element with id :id should be at the top of the page` | `Then the element :selector should be at the top of the viewport` | -|   -| **`KeyboardTrait`** | **`KeyboardTrait`** | -| `Given I press the :keys keys` | `When I press the keys :keys` | -| `Given I press the :keys keys on :selector` | `When I press the keys :keys on the element :selector` | -| `Given I press the :char key` | `REMOVED` | -| `Given I press the :char key on :selector` | `REMOVED` | -|   | | -| **`LinkTrait`** | **`LinkTrait`** | -| `Then I should see the link :text with :href` | `Then the link :link with the href :href should exist` | -| `Then I should see the link :text with :href in :locator` | `Then the link :link with the href :href within the element :locator should exist` | -| `Then I should not see the link :text with :href` | `Then the link :link with the href :href should not exist` | -| `Then I should not see the link :text with :href in :locator` | `Then the link :link with the href :href within the element :locator should not exist` | -| `Then the link with title :title exists` | `Then the link with the title :title should exist` | -| `Then the link with title :title does not exist` | `Then the link with the title :title should not exist` | -| `Then I click the link with title :title` | `When I click on the link with the title :title` | -| `Then the link( with title) :text is an absolute link` | `Then the link :link should be an absolute link` | -| `Then the link( with title) :text is not an absolute link` | `Then the link :link should not be an absolute link` | -|   -| **`MediaTrait`** | **`Drupal\MediaTrait`** | -| `Given no :type media type` | `Given :media_type media type does not exist` | -| `Given :type media:` | `Given the following media :media_type exist:` | -| `Given /^no ([a-zA-z0-9_-]+) media:$/` | `Given the following media :media_type do not exist:` | -| `When I edit :type media :name` | `When I edit the media :media_type with the name :name` | -|   -| **`MenuTrait`** | **`Drupal\MenuTrait`** | -| `Given no menus:` | `Given the menu :menu_name does not exist` | -| `Given menus:` | `Given the following menus:` | -| `Given no :menu_name menu_links:` | `Given the following menu links do not exist in the menu :menu_name:` | -| `Given :menu_name menu_links:` | `Given the following menu links exist in the menu :menu_name:` | -|   -| **`MetatagTrait`** | **`MetatagTrait`** | -| `Then I should see a meta tag with the following attributes:` | `Then the meta tag should exist with the following attributes:` | -| `Then I should not see a meta tag with the following attributes:` | `Then the meta tag should not exist with the following attributes:` | -|   | | -| **`ParagraphsTrait`** | **`Drupal\ParagraphsTrait`** | -| `When :field_name in :bundle :entity_type with :entity_field_name of :entity_field_identifer has :paragraph_type paragraph:` | `Given the following fields for the paragraph :paragraph_type exist in the field :parent_field within the :parent_bundle :parent_entity_type identified by the field :parent_lookup_field and the value :parent_lookup_value:` | -|   | | -| **`PathTrait`** | **`PathTrait`** | -| `Then I should be in the :path path` | `Then the path should be :path` | -| `Then I should not be in the :path path` | `Then the path should not be :path` | -| `Then I :can visit :path with HTTP credentials :user :pass` | `Given the basic authentication with the username :username and the password :password` | -| `When I visit :path then the final URL should be :alias` | Removed. Use `When I visit :path` and `Then the path should be :path` | -|   | | -| **`ResponseTrait`** | **`ResponseTrait`** | -| `Then response contains header :name` | `Then the response should contain the header :header_name` | -| `Then response does not contain header :name` | `Then the response should not contain the header :name` | -| `Then response header :name contains :value` | `Then the response header :name should contain the value :value` | -| `Then response header :name does not contain :value` | `Then the response header :name should not contain the value :value` | -|   | | -| **`RoleTrait`** | **`Drupal\UserTrait`** | -| `Given role :name with permissions :permissions` | `Given the role :role with the permissions :permissions` | -| `Given roles:` | `Given the following roles:` | -|   | | -| **`SelectTrait`** | **`ElementTrait`** | -| `Then select :select should have an option :option` | `Then the option :option should exist within the select element :selector` | -| `Then select :select should not have an option :option` | `Then the option :option should not exist within the select element :selector` | -| `Then /^the option "([^"]*)" from select "([^"]*)" is selected$/` | `Then the option :option should be selected within the select element :selector` | -| `NEW` | `Then the option :option should not be selected within the select element :selector` | -|   | | -| **`SearchApiTrait`** | **`Drupal\SearchApiTrait`** | -| `When I index :type :title for search` | `When I add the :content_type content with the title :title to the search index` | -| `When I index :limit Search API items` | `When I run search indexing for :count item(s)` | -|   | | -| **`TaxonomyTrait`** | **`Drupal\TaxonomyTrait`** | -| `Given no :vocabulary terms:` | `Given the following :vocabulary_machine_name vocabulary terms do not exist:` | -| `Given vocabulary :vid with name :name exists` | `Then the vocabulary :machine_name with the name :name should exists` | -| `Given taxonomy term :name from vocabulary :vocabulary_id exists` | `Then the taxonomy term :term_name from the vocabulary :vocabulary_machine_name should exist` | -| `When I visit :vocabulary vocabulary term :name` | `When I visit the :vocabulary_machine_name vocabulary :term_name term page` | -| `When I edit :vocabulary vocabulary term :name` | `When I edit the :vocabulary_machine_name vocabulary :term_name term page` | -|   | | -| **`UserTrait`** | **`Drupal\UserTrait`** | -| `Given no users:` | `Given the following users do not exist:` | -| `When I visit user :name profile` | `When I visit :name user profile page` | -| `When I go to my profile edit page` | `When I visit my own user profile edit page` | -| `When I edit user :name profile` | `When I visit :name user profile edit page` | -| `Then user :name has :roles role(s) assigned` | `Then the user :name should have the role(s) :roles assigned` | -| `Then user :name does not have :roles role(s) assigned` | `Then the user :name should not have the role(s) :roles assigned` | -| `Then user :name has :status status` | `Then the user :name should be blocked` and `Then the user :name should not be blocked` | -| `Then I set user :user password to :password` | `Given the password for the user :name is :password` | -| `Then the last access time of user :name is :time` | `Given the last access time for the user :name is :datetime` | -|   | | -| **`VisibilityTrait`** | **`ElementTrait`** | -| `Then /^(?:I)should see a visible "(?P[^"]*)" element$/` | `Then the element :selector should be displayed` | -| `Then /^(?:I)should not see a visible "(?P[^"]*)" element$/` | `Then the element :selector should not be displayed` | -| `Then /^(?:I)should see a visually visible "(?P[^"]*)" element(?: with top offset of "([^"]*)" pixels)?$/` | `Then the element :selector should be displayed within a viewport` | -| `NEW` | `Then the element :selector should be displayed within a viewport with a top offset of :number pixels` | -| `Then /^(?:I)should not see a visually hidden "(?P[^"]*)" element(?: with top offset of "([^"]*)" pixels)?$/` | `Then the element :selector should not be displayed within a viewport` | -| `NEW` | `Then the element :selector should not be displayed within a viewport with a top offset of :number pixels` | -|   | | -| **`WaitTrait`** | **`WaitTrait`** | -| `Then /^(?:\|I )wait (\d+) second(s?)$/` | `When I wait for :number second(s)` | -| `Given I wait :timeout seconds for AJAX to finish` | `When I wait for :number second(s) for AJAX to finish` | diff --git a/README.md b/README.md index 95cad17a..4bbeaefe 100644 --- a/README.md +++ b/README.md @@ -105,183 +105,6 @@ from the community. composer require --dev drevops/behat-steps:^3 ``` -> [!TIP] -> Upgrading from [`2.x`](https://github.com/drevops/behat-steps/tree/2.x)? -> We’ve updated the steps language for greater consistency -> and clarity. Please refer to the [migration map](MIGRATION.md) to see the -> changes. An automated migration script is not included, but an AI-guided -> migration prompt is provided below. - -
-🤖 Expand to get an AI prompt for features migration - -Copy and paste below into your agentic AI client chat. - -``` -# Guide to Updating Behat Steps Package in Drupal Projects - -This guide explains how to update the drevops/behat-steps package to the latest version and update your Behat tests to work with the new step definitions. - -## Overview of the Update Process - -1. Update the package version in composer.json -2. Update namespace imports in FeatureContext.php -3. Update step definitions in feature files -4. Test and fix each feature file - -## Step-by-Step Instructions - -### 1. Update the Package - -First, check your current version of drevops/behat-steps in composer.json. Then update to the latest version (3.0.1 or newer) using your project's package management tool. - -### 2. Fix FeatureContext.php - -The namespace structure has changed in version 3.0.1. You'll need to update your FeatureContext.php file: - -1. Locate your FeatureContext.php file (typically in tests/behat/bootstrap/) -2. Update the namespace imports at the top of the file - - Generic traits are now in the root namespace: `DrevOps\BehatSteps\` - - Drupal-specific traits are now in a subdirectory: `DrevOps\BehatSteps\Drupal\` - -For example, change: - - use DrevOps\BehatSteps\ContentTrait; - use DrevOps\BehatSteps\FileTrait; - -To: - - use DrevOps\BehatSteps\Drupal\ContentTrait; - use DrevOps\BehatSteps\Drupal\FileTrait; - -Non-Drupal traits remain in the root namespace: - - use DrevOps\BehatSteps\LinkTrait; - use DrevOps\BehatSteps\PathTrait; - use DrevOps\BehatSteps\ResponseTrait; - use DrevOps\BehatSteps\WaitTrait; - -### 3. Consult the STEPS.md File - -**This is the most important reference for the update process!** - -The drevops/behat-steps package includes a comprehensive STEPS.md file that documents all available steps. After updating the package: - -1. Locate this file at `vendor/drevops/behat-steps/STEPS.md` -2. Review this file thoroughly - it contains all available steps with examples -3. Use this as your primary reference when updating feature files - -The STEPS.md file is organized into sections: -- Generic steps (Cookie, Date, Element, Path, etc.) -- Drupal-specific steps (Content, Field, File, Media, etc.) - -Each section includes detailed examples of how to use the steps, which is invaluable for updating your tests correctly. - -### 4. Find and Update Feature Files - -Examine your feature files (typically in tests/behat/features/) and update step definitions to match the new format from STEPS.md: - -#### Common Changes Needed: - -1. **Path Assertions**: - - Change: `I should be in the "path" path` - - To: `the path should be "path"` - -2. **HTTP Response Assertions**: - - Change: `I should get a 200 HTTP response` - - To: `the response status code should be 200` - -3. **Response Header Assertions**: - - Change: `response header "X-Header" contains "value"` - - To: `the response header "X-Header" should contain the value "value"` - -4. **Link Interaction**: - - Change: `I click the link with title "Title"` - - To: `I click on the link with the title "Title"` or simply `I click "Title"` - -5. **Wait Steps**: - - Change: `I wait 2 seconds` - - To: `I wait for 2 seconds` - -6. **File Creation**: - - Change: `unmanaged file "public://file.txt" created with content "content"` - - To: `the unmanaged file at the URI "public://file.txt" exists with "content"` - -7. **Content Visiting**: - - Change: `I visit content_type "Title"` - - To: `I visit the "content_type" content page with the title "Title"` - -### 5. Reference Available Steps - -There are two ways to see all available steps in the new package: - -1. **STEPS.md File (Recommended)**: - - This is the most comprehensive and user-friendly reference - - Contains examples and descriptions for each step - - Located at `vendor/drevops/behat-steps/STEPS.md` - -2. **Behat Definitions Command**: - - Use the Behat definitions command appropriate for your system: - - vendor/bin/behat --definitions=i - - - This will show all available step definitions but with less context than STEPS.md - -Always refer to STEPS.md first, as it provides clearer examples and more detailed information about each step. - -### 6. Test Each Feature File - -After updating step definitions: - -1. Run each feature file individually to identify any issues -2. For failing tests, check screenshots if available to help diagnose the problems -3. Add `@skipped` tag to features that aren't ready to run (you can fix these later) -4. Once individual files pass, run the entire test suite - -### 7. Common Troubleshooting - -- **Step Not Found**: Verify you're using the current step syntax by checking the step definitions -- **Element Not Found**: The site structure may have changed - update selectors or navigation paths -- **Form Submission Issues**: For form tests, consider checking for broader success indicators rather than specific messages - -### Reference Information - -The STEPS.md file is your most important reference during this process. It contains: - -1. Complete documentation of all available steps -2. Clear examples showing the exact format for each step -3. Descriptions of what each step does -4. Organization by trait/functionality for easy browsing - -After updating the package, you should immediately locate and bookmark this file: - - vendor/drevops/behat-steps/STEPS.md - -If you need to understand specific Behat step behavior in detail, this file should be your first resource. - -## Example: Updating a Contact Form Feature - -Before: - - Scenario: User submits a form - Given I am on the homepage - And I click the link with title "Contact" - When I fill in "Name" with "Test User" - And I press "Send message" - Then I should see the text "Your message has been sent." - -After: - - Scenario: User submits a form - Given I am on the homepage - And I click "Contact" - When I fill in "Name" with "Test User" - And I press "Send message" - Then I should not see an "#edit-submit" element -``` - -
- ## Usage Add required traits to your