From 72ce1258dfde164cc607252ba85a7f31e9ccfd1d Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 24 Nov 2024 13:42:39 -0300 Subject: [PATCH 1/3] Rename examples to be "example-plugin", etc --- docs/custom-tests/01-generating-tests.md | 4 +- docs/custom-tests/02-tagging-tests.md | 18 +- docs/custom-tests/03-running-tests.md | 66 ++--- .../04-running-other-plugins-tests.md | 12 +- .../05-bootstrap-and-test-phases.md | 248 +++++++++--------- docs/custom-tests/06-themes.md | 2 +- 6 files changed, 179 insertions(+), 171 deletions(-) diff --git a/docs/custom-tests/01-generating-tests.md b/docs/custom-tests/01-generating-tests.md index 4663b08..6cdbe97 100644 --- a/docs/custom-tests/01-generating-tests.md +++ b/docs/custom-tests/01-generating-tests.md @@ -59,7 +59,7 @@ When you generate tests with `--codegen`, they will be generated with the URLs y ```js await page.goto('http://localhost:32456'); -await page.goto('http://localhost:32456?cat=pictures'); +await page.goto('http://localhost:32456?action=foo'); await page.goto('http://localhost:32456/my-page'); await page.goto('http://localhost:32456/wp-admin'); ``` @@ -70,7 +70,7 @@ After pasting it in a test file, remove the URLs, as the test run uses a `baseUR ```js await page.goto('/'); -await page.goto('/?cat=pictures'); +await page.goto('/?action=foo'); await page.goto('/my-page'); await page.goto('/wp-admin'); ``` diff --git a/docs/custom-tests/02-tagging-tests.md b/docs/custom-tests/02-tagging-tests.md index c75d61a..a6969be 100644 --- a/docs/custom-tests/02-tagging-tests.md +++ b/docs/custom-tests/02-tagging-tests.md @@ -21,7 +21,7 @@ qit tag:list To list the test tags for a specific plugin/theme: ```qitbash -qit tag:list qit-beaver +qit tag:list example-plugin ``` ## Uploading tests @@ -29,7 +29,7 @@ qit tag:list qit-beaver You can upload your tests and make them available as a tag with the command: ```qitbash -qit tag:upload qit-beaver /path/to/tests +qit tag:upload example-plugin /path/to/tests ``` By default, the test will be uploaded as the `default` tag. @@ -37,7 +37,7 @@ By default, the test will be uploaded as the `default` tag. If you want to specify a test tag, you can add the tag in this format: `extension:tag`: ```qitbash -qit tag:upload qit-beaver:my-tag /path/to/tests +qit tag:upload example-plugin:my-tag /path/to/tests ``` ## Running test tags @@ -45,23 +45,23 @@ qit tag:upload qit-beaver:my-tag /path/to/tests Now you can run your test both locally and in CI using the `default` tag: ```qitbash -qit run:e2e qit-beaver +qit run:e2e example-plugin ``` Or, if it's a specific tag: ```qitbash -qit run:e2e qit-beaver my-tag +qit run:e2e example-plugin my-tag ``` ## Running test tags from other plugins Other developers that have access to your extension can also use your tests for compatibility testing. -Let's suppose that `qit-dog` has published their tests. You can run your tests and theirs with: +Let's suppose that `example-plugin-2` has published their tests. You can run your tests and theirs with: ```qitbash -qit run:e2e qit-beaver --plugin qit-dog:test +qit run:e2e example-plugin --plugin example-plugin-2:test ``` ## Running multiple tags @@ -69,7 +69,7 @@ qit run:e2e qit-beaver --plugin qit-dog:test You can also compose multiple tags by passing a comma-separated list of test tags: ```qitbash -qit run:e2e qit-beaver default,rc --plugin qit-dog:test:feature-dog-pictures +qit run:e2e example-plugin default,rc --plugin example-plugin-2:test:some-feature ``` ## Deleting test tags @@ -77,5 +77,5 @@ qit run:e2e qit-beaver default,rc --plugin qit-dog:test:feature-dog-pictures You can delete test tags that you have previously published: ```qitbash -qit tag:delete qit-beaver:my-tag +qit tag:delete example-plugin:my-tag ``` diff --git a/docs/custom-tests/03-running-tests.md b/docs/custom-tests/03-running-tests.md index 03bc165..0b232b5 100644 --- a/docs/custom-tests/03-running-tests.md +++ b/docs/custom-tests/03-running-tests.md @@ -12,17 +12,17 @@ The custom E2E tests feature is available as early-access. Assuming you have generated and uploaded a E2E test, the basic syntax for running a test is: ```qitbash -qit run:e2e qit-beaver +qit run:e2e example-plugin ``` If you haven't uploaded a test to QIT, you can run a local test: ```qitbash -qit run:e2e qit-beaver ~/my-plugins/qit-beaver/tests +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests ``` :::tip -Replace "qit-beaver" with the slug of an extension you own. +Replace "example-plugin" with the slug of an extension you own. ::: ## Using a config file @@ -45,11 +45,11 @@ values={[ "php_version": "8.3", "object_cache": true, "plugins": { - "qit-beaver": { + "example-plugin": { "action": "test", - "source": "~/my-plugins/qit-beaver", + "source": "~/my-plugins/example-plugin", "test_tags": [ - "~/my-plugins/qit-beaver/tests" + "~/my-plugins/example-plugin/tests" ] }, "woocommerce": { @@ -61,12 +61,12 @@ values={[ "foo-plugin": { "action": "install" }, - "qit-dog": { + "example-plugin-2": { "action": "test", - "source": "https://github.com/qit-plugins/qit-dog/releases/tag/nightly.zip", + "source": "https://github.com/qit-plugins/example-plugin-2/releases/tag/nightly.zip", "test_tags": [ "nightly", - "feature-dog-pictures" + "some-feature" ] } } @@ -80,23 +80,23 @@ wordpress_version: nightly php_version: 8.3 object_cache: true plugins: - qit-beaver: + example-plugin: action: test - source: ~/.qit/plugins/qit-beaver + source: ~/.qit/plugins/example-plugin test_tags: - - ~/my-plugins/qit-beaver/tests + - ~/my-plugins/example-plugin/tests woocommerce: action: bootstrap test_tags: - default foo-plugin: action: install - qit-dog: + example-plugin-2: action: test - source: https://github.com/qit-plugins/qit-dog/releases/tag/nightly.zip + source: https://github.com/qit-plugins/example-plugin-2/releases/tag/nightly.zip test_tags: - nightly - - feature-dog-pictures + - some-feature ``` @@ -109,13 +109,13 @@ You can also mimick this entire config file using only runtime parameters. Suppose you are scripting a test run and want to pass everything as parameters: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests --source ~/.qit/plugins/qit-beaver \ +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/.qit/plugins/example-plugin \ --wp nightly \ --php-version 8.3 \ --object-cache \ --plugin woocommerce:bootstrap \ --plugin foo-plugin:activate \ - --plugin https://github.com/qit-plugins/qit-dog/releases/tag/nightly.zip:test:nightly,feature-dog-pictures:qit-dog + --plugin https://github.com/qit-plugins/example-plugin-2/releases/tag/nightly.zip:test:nightly,some-feature:example-plugin-2 ``` ## The plugin syntax @@ -144,9 +144,9 @@ Examples: ``` # Scenarios wehere inferred `slug` is `extension2`: -qit run:e2e qit-beaver --plugin extension2 -qit run:e2e qit-beaver --plugin ~/my-plugins/qit-beaver/extension2.zip -qit run:e2e qit-beaver --plugin https://github.com/woocommerce/qit-beaver/releases/tag/extension2.zip +qit run:e2e example-plugin --plugin extension2 +qit run:e2e example-plugin --plugin ~/my-plugins/example-plugin/extension2.zip +qit run:e2e example-plugin --plugin https://github.com/woocommerce/example-plugin/releases/tag/extension2.zip ``` ## Examples: @@ -156,19 +156,19 @@ qit run:e2e qit-beaver --plugin https://github.com/woocommerce/qit-beaver/releas Directory as `source`: ```qitbash -qit run:e2e qit-the-beaver --source ~/my-plugins/qit-beaver +qit run:e2e qit-the-beaver --source ~/my-plugins/example-plugin ``` Zip file as `source`: ```qitbash -qit run:e2e qit-the-beaver --source ~/my-plugins/qit-beaver/qit-beaver.zip +qit run:e2e qit-the-beaver --source ~/my-plugins/example-plugin/example-plugin.zip ``` URL as `source`: ```qitbash -qit run:e2e qit-the-beaver --source https://github.com/woocommerce/qit-beaver/releases/tag/qit-beaver.zip +qit run:e2e qit-the-beaver --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip ``` @@ -179,25 +179,25 @@ If you have a test that you haven't uploaded yet, you can run it directly: Slug as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests ``` Directory as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests --source ~/my-plugins/qit-beaver +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin ``` Zip file as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests --source ~/my-plugins/qit-beaver/build.zip +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin/build.zip ``` URL as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests --source https://github.com/woocommerce/qit-beaver/releases/tag/nightly.zip +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source https://github.com/woocommerce/example-plugin/releases/tag/nightly.zip ``` ## Using test tags @@ -205,33 +205,33 @@ qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests --source https://github If you have uploaded a test with a tag different than the default one, you can run it with: ```qitbash -qit run:e2e qit-beaver nightly +qit run:e2e example-plugin nightly ``` You can also run multiple tags: ```qitbash -qit run:e2e qit-beaver nightly,foo-feature +qit run:e2e example-plugin nightly,foo-feature ``` And you can run a test with a tag from a local directory, file, or URL: ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/qit-beaver +qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/example-plugin ``` ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/qit-beaver/qit-beaver.zip +qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/example-plugin/example-plugin.zip ``` ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source https://github.com/woocommerce/qit-beaver/releases/tag/qit-beaver.zip +qit run:e2e qit-the-beaver nightly,foo-feature --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip ``` And even run a local test in the mix: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/qit-beaver/tests,nightly,foo-feature --source ~/my-plugins/qit-beaver +qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests,nightly,foo-feature --source ~/my-plugins/example-plugin ``` ## Testing plugins that require a live site diff --git a/docs/custom-tests/04-running-other-plugins-tests.md b/docs/custom-tests/04-running-other-plugins-tests.md index cf5d096..f099b37 100644 --- a/docs/custom-tests/04-running-other-plugins-tests.md +++ b/docs/custom-tests/04-running-other-plugins-tests.md @@ -15,17 +15,17 @@ This is useful for compatibility testing, or to run tests that are not part of y To run a test from another plugin, you can use the `--plugin` flag: ```qitbash -qit run:e2e qit-beaver --plugin cat-pictures +qit run:e2e example-plugin --plugin example-plugin ``` -In this example, `qit-beaver` is the SUT (System-Under-Test), and `cat-pictures` is an additional plugin. +In this example, `example-plugin` is the SUT (System-Under-Test), and `example-plugin` is an additional plugin. By default, the SUT always runs the bootstrap and test phases. The additional plugin only runs the bootstrap phase. You can also run the test phase of the additional plugin by passing a flag: ```qitbash -qit run:e2e qit-beaver --plugin cat-pictures:test +qit run:e2e example-plugin --plugin example-plugin:test ``` Now the test phases of both plugins are run. This is useful for ensuring that your plugin does not break the expected behavior of other plugins. @@ -44,8 +44,8 @@ This will print a table like this: +-----------------------+---------------+--------+ | Slug | E2E Tests | Type | +-----------------------+---------------+--------+ -| qit-beaver | default | plugin | -| cat-pictures | rc, default | plugin | +| example-plugin | default | plugin | +| example-plugin | rc, default | plugin | +-----------------------+---------------+--------+ ``` @@ -56,5 +56,5 @@ This table shows the available test tags for each plugin. You can use these tags You can run multiple tests by passing a comma-separated list of tags: ```qitbash -qit run:e2e qit-beaver --plugin cat-pictures:test:rc,default +qit run:e2e example-plugin --plugin example-plugin:test:rc,default ``` diff --git a/docs/custom-tests/05-bootstrap-and-test-phases.md b/docs/custom-tests/05-bootstrap-and-test-phases.md index e7c765a..4b64a62 100644 --- a/docs/custom-tests/05-bootstrap-and-test-phases.md +++ b/docs/custom-tests/05-bootstrap-and-test-phases.md @@ -1,137 +1,145 @@ import CustomTestsDiagram from '@site/src/img/custom-tests-diagram.png'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - -# Bootstrap and test phases - -:::info +# Bootstrap and Test Phases The custom E2E tests feature is available as early-access. -::: - ## Introduction +The E2E Tests are structured to ensure that each plugin is tested in a clean environment while efficiently managing shared resources. The key phases are: +1. **Preparation Phase** +2. **Setup Phase** +3. **Teardown Phase** +4. **Shared Setup** +5. **Shared Teardown** +6. **Post-Processing**This progressive structure allows for a systematic approach to testing, starting from individual plugin setups to shared configurations.Here's the flow of execution: +## The Preparation Phase +Before diving into the setup phases, the system prepares the testing environment: +- **Start Environment**: The Tester initiates the process. +- **Download Plugins and Themes**: All necessary plugins and themes are downloaded. +- **Start Docker Environment**: A Docker environment is initialized to ensure isolation. +- **Install WordPress**: WordPress is installed within the Docker environment. +- **Activate Plugins**: Plugins are activated. +- **Move Must-Use Plugins**: Any must-use plugins are moved to the appropriate directory. + + +## 1. Setup Phase +In the **Setup Phase**, you prepare everything your tests need and perform the initial setup of your plugin. This phase is specific to each plugin and ensures that any plugin-specific configurations are in place before the tests run. +### What to Include in the Setup Phase -The E2E Tests have three key parts: the **Bootstrap Phase**, the **Entrypoint**, and the **Test Phase**. - -This is the flow of execution: - - - -## The bootstrap phase - -In this phase, set up everything your tests needs, and do the initial setup of your plugin. - -If you plugin has an onboarding wizard, this is where you need to configure it so that it doesn't show up anymore. Get rid of any data consent forms, or any other setup that needs to be done before the tests run. - -If your plugin integrates with an external service, here's where you can configure mock responses, enable a development mode or anything else you need. - -If your tests expects a specific theme to be active, you **install** them in this step so that they are available on your Test Phase, and you **activate it** in the beginning of your Test Phase eg: - -**bootstrap.sh** - -```bash -# Install Storefront Theme so that we can activate it on our Test phase. -wp theme install storefront -``` - -### `bootstrap.sh` - -This is a bash script that, if present, will be called. Here you can use `wp` (WP-CLI) and bash in general. - -### `bootstrap.php` - -This is a PHP file that, if present, will be called. WordPress is NOT loaded on the context of this file. - -### `mu-plugin.php` - -This is a file that, if present, will be copied to the `wp-content/mu-plugins` directory and will run on ALL requests on the E2E test. WordPress is loaded on the context of this file. - -If you want to put logic in there that should run only once, make sure to set a flag to prevent it from running multiple times. - -### Where to put the bootstrap files +- **Configure Onboarding Wizards**: If your plugin has an onboarding wizard, configure it to prevent it from appearing during tests. +- **Disable Data Consent Forms**: Remove any data consent prompts or initial setup screens. +- **Mock External Services**: If your plugin integrates with external services, set up mock responses or enable a development mode. +- **Install Themes**: If your tests require a specific theme, **install** it during this phase so it’s available during the Test Phase. +### Setup Files +You can use the following files in your setup phase: +#### `bootstrap.sh` + +- A bash script that, if present, will be executed. +- Use `wp` (WP-CLI) commands and bash scripting to set up your environment.**Example:** +#### `bootstrap.php` + +- A PHP file that, if present, will be executed. +- Note: WordPress is **not loaded** in the context of this file. +#### `mu-plugin.php` + +- A must-use plugin file that, if present, will be copied to the `wp-content/mu-plugins` directory. +- This file runs on **all requests** during the E2E test. +- WordPress **is loaded** in the context of this file. +- For logic that should run only once, set a flag to prevent multiple executions. +### Where to Place the Setup Files +Place your setup files in the `bootstrap` directory within your E2E test suite:**Note:** You can organize your tests in any way that suits your project structure. + + +## 2. Teardown Phase +After your tests have run, the **Teardown Phase** is responsible for cleaning up any changes made during the Setup and Test Phases. This ensures that the environment is reset and ready for the next set of tests. +### What to Include in the Teardown Phase + +- **Deactivate Plugins**: Deactivate any plugins activated during setup. +- **Remove Test Data**: Delete any test data or configurations added during testing. +- **Reset Mock Services**: Reset any mocks or stubs used for external services. +### Teardown Files +You can use the following files in your teardown phase: +#### `teardown.sh` + +- A bash script that, if present, will be executed. +- Use `wp` (WP-CLI) commands and bash scripting to clean up your environment. +#### `teardown.php` + +- A PHP file that, if present, will be executed. +- Note: WordPress is **not loaded** in the context of this file. +#### `mu-plugin.php` + +- A must-use plugin file for teardown, if needed. +- Place any teardown logic that needs to run on all requests here. +- Remember to set flags to prevent multiple executions if necessary. +### Where to Place the Teardown Files +Place your teardown files in a `teardown` directory within your E2E test suite: + + +## 3. Shared Setup +The **Shared Setup** phase involves running setup scripts that are common across all plugins. This phase is useful for setting up shared dependencies or configurations that multiple plugins might require. +### What to Include in the Shared Setup Phase + +- **Install Shared Themes or Plugins**: Install any themes or plugins that are required by multiple plugins. +- **Configure Global Settings**: Set up WordPress settings that are common across tests. +- **Prepare Shared Data**: Import or generate data that will be used by multiple plugins. +### Shared Setup Files +Place your shared setup scripts in the `shared-setup` directory: +#### `bootstrap.sh` + +- Contains shared bash scripts for setting up the environment. +#### `bootstrap.php` + +- Contains shared PHP scripts for setup. +#### `mu-plugin.php` + +- Shared must-use plugin that runs during all requests. +### Where to Place the Shared Setup Files + + + +## 4. Shared Teardown +After all plugin tests are completed, the **Shared Teardown** phase cleans up any shared resources or configurations set during the Shared Setup phase. +### What to Include in the Shared Teardown Phase + +- **Deactivate Shared Plugins/Themes**: Remove any shared plugins or themes installed. +- **Reset Global Settings**: Revert any global settings to their defaults. +- **Clean Up Shared Data**: Delete any shared data that was created. +### Shared Teardown Files +Place your shared teardown scripts in the `shared-teardown` directory: +#### `teardown.sh` + +- Contains shared bash scripts for cleaning up the environment. +#### `teardown.php` -Place them in the bootstrap directory within your E2E test suite. Here’s how your directory structure should look: +- Contains shared PHP scripts for teardown. +#### `mu-plugin.php` -``` -bootstrap (Optional) - bootstrap.php (Optional) - bootstrap.sh (Optional) - mu-plugin.php (Optional) -entrypoint.js (Optional) -example.spec.js -``` +- Shared must-use plugin for teardown logic. +### Where to Place the Shared Teardown Files -**You can put the tests anywhere you want**, even outside the plugin structure. Just for example purposes, here's what a typical directory structure could look like, using the `qit-beaver` plugin as an example: -``` -. -├── tests # Test files directory -│ └── e2e # End-to-end test suite -│ ├── bootstrap # Bootstrap files for setting up tests -│ │ ├── bootstrap.php -│ │ ├── bootstrap.sh -│ │ └── mu-plugin.php -│ ├── entrypoint.js # The Test Phase entrypoint -│ └── example.spec.js # E2E test file -├── src # QIT Beaver Source code -└── qit-beaver.php # Main plugin file -``` -## The entrypoint +## 5. The Entry Point +The `entrypoint.js` is a file that, if present, will be executed when your **Test Phase** starts. This is an ideal place to perform plugin-specific initializations, such as activating a theme that you have previously installed during the Setup Phase. +### Where to Place the Entry Point +Place the `entrypoint.js` in the root of your E2E test suite: -The `entrypoint.js` is a file that, if present, will be called when your **Test Phase** starts. This is a good place to put any setup logic, such as **activating** a theme that you have previously **installed** in the Bootstrap Phase. -## The test phase +## 6. The Test Phase +This is where the actual testing happens. We utilize Playwright to interact with the browser and verify your plugin's functionality. +### Running Your Tests +By default, only the test phase of the plugin you're running tests from will be executed. +#### E2E Test Command +To run the E2E tests for your plugin without testing others, use:This command will: +- Run the **Setup Phase** and **Teardown Phase** of your plugin. +- Skip the test phases of other plugins. +#### Compatibility Test Command +To run a full compatibility test including other plugins, use:This command will: +- Run the **Shared Setup** and **Shared Teardown** phases. +- Execute the **Setup**, **Test**, and **Teardown** phases for all plugins that have tests published to QIT. -This is where the actual testing happens. We utilize Playwright to interact with the browser and verify your plugin's functionality. By default, the only test phase that gets executed is the one from the plugin you are running the tests from. - -:::tip -When running with the test phase of other plugins, any flakiness in the tests of other plugins can cause your tests to fail. -::: - -### E2E test - -If you run this command: `qit run:e2e qit-the-beaver --plugin cat-pictures`: - -- Run the bootstrap phases of all the plugins -- **Run the test phase of `qit-the-beaver`** - -### Compatibility test - -If instead you want to run a full compatibility test, you can run, `qit run:e2e qit-the-beaver --plugin cat-pictures:test`, it will: - -- Run the bootstrap phases of the `default` test tag of all the plugins -- **Run the test phase of the `default` test tag all plugins, if they have tests published to QIT** - -Essentially, when you run your test phase and other plugin's bootstrap phases, you are asserting that your plugin continues to behave as expected when other plugins are installed and configured in a site. - -When you run other plugin's test phases as well, you have the coverage above, plus you are asserting that your plugin does not break other plugins. - -The test phase is composed of 4 sub-phases: - -### 1. Setup - -A database dump that was generated after the bootstrap phase is imported, which provides a clean state for each the test phase of each plugin. - -### 2. Entrypoint - -The `entrypoint.js` is executed, if it exists. - -### 3. Tests - -The tests of that plugin are executed. - -If you have installed a Theme in the Bootstrap Phase, you can activate it here: - -``` -tests - bootstrap - bootstrap.sh - entrypoint.js - example.spec.js -``` ## Environment Variables +You can use environment variables in your tests to pass secrets or configurations without hardcoding them.Refer to the [Environment Variables](https://chatgpt.com/docs/environment/environment-variables) documentation for more information. -You can use environment variables in your tests, for passing secrets or configuration that you don't want to hardcode in your tests. - -Refer to the [Environment Variables](/docs/environment/environment-variables) documentation for more information. \ No newline at end of file +By structuring your documentation in this progressive manner, readers can build their understanding step by step. Starting with the basic setup and teardown processes, and then introducing shared setup and teardown concepts, allows users to grasp the foundational elements before moving on to more complex configurations.If you need further assistance or have any questions about implementing these phases, feel free to ask! \ No newline at end of file diff --git a/docs/custom-tests/06-themes.md b/docs/custom-tests/06-themes.md index d0d70d9..54bfd52 100644 --- a/docs/custom-tests/06-themes.md +++ b/docs/custom-tests/06-themes.md @@ -46,5 +46,5 @@ This entrypoint was generated with Codegen. The easiest way is to start a codege If you are developing a theme, the previous section applies as well. And when you run it, be sure to add the `--testing_theme` flag: ```qitbash -qit run:e2e qit-beaver-theme --testing_theme +qit run:e2e example-plugin-theme --testing_theme ``` From 9c801cf4c47ed8e1e4c99caa3d4bea85acf07980 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sun, 24 Nov 2024 20:23:52 -0300 Subject: [PATCH 2/3] Orchestration/lifecycle docs --- docs/custom-tests/01-generating-tests.md | 35 ++++- docs/custom-tests/02-tagging-tests.md | 6 +- docs/custom-tests/03-running-tests.md | 26 ++-- .../04-running-other-plugins-tests.md | 60 -------- .../04-understanding-lifecycle.md | 104 +++++++++++++ .../05-bootstrap-and-test-phases.md | 145 ------------------ docs/environment/01-getting-started.md | 2 +- docs/environment/02-creating-config-files.md | 2 +- .../04-installing-plugins-other-sources.md | 8 +- src/img/custom-tests-diagram.png | Bin 46049 -> 47947 bytes 10 files changed, 158 insertions(+), 230 deletions(-) delete mode 100644 docs/custom-tests/04-running-other-plugins-tests.md create mode 100644 docs/custom-tests/04-understanding-lifecycle.md delete mode 100644 docs/custom-tests/05-bootstrap-and-test-phases.md diff --git a/docs/custom-tests/01-generating-tests.md b/docs/custom-tests/01-generating-tests.md index 6cdbe97..3741057 100644 --- a/docs/custom-tests/01-generating-tests.md +++ b/docs/custom-tests/01-generating-tests.md @@ -16,14 +16,15 @@ This will create a basic E2E test in the `e2e` directory with essentially a `exa ``` bootstrap (Optional) - bootstrap.sh - bootstrap.php + setup.js + setup.sh + dependencies.json mu-plugin.php example.spec.js ``` :::tip -Bootstrap files are optional and can be removed if not needed. [Learn more about bootstrapping](/docs/custom-tests/bootstrap-and-test-phases) and its use cases. +Bootstrap files are optional and can be removed if not needed. [Learn more about bootstrapping](/docs/custom-tests/understanding-lifecycle) and its use cases. ::: You can run your first test locally with: @@ -36,6 +37,33 @@ qit run:e2e ./e2e You can then expand it with more tests, or even generate tests with Playwright Codegen. +## Advanced Scaffolding + +When scaffolding, you can also include shared setups and teardowns. Refer to the [Understanding Lifecycle](/docs/custom-tests/understanding-lifecycle) documentation for more information. + +```qitbash +qit scaffold:e2e ./e2e --with-shared --with-teardown +``` + +This will give you the following structure: + +``` +bootstrap + setup.js (Playwright file that runs in isolation before your tests) + setup.sh (Bash file that runs in isolation before your tests) + shared-setup.js (Playwright file that runs before all tests in a compatibility test) + shared-setup.sh (Bash file that runs before all tests in a compatibility test) + shared-teardown.js (Playwright file that runs after all tests in a compatibility test) + shared-teardown.sh (Bash file that runs after all tests in a compatibility test) + teardown.js (Playwright file that runs in isolation after your tests) + teardown.sh (Bash file that runs in isolation after your tests) +example.spec.js +``` + +When you run a compatibility test (eg: `qit run:e2e example-plugin --plugin example-plugin:test`), a database snapshot is taken after the shared setup, and restored for each plugin test. The shared teardown is run after all tests are done. + +Anything you do in your isolated setup and teardown files will only affect your plugin's test environment. Anything you do in the shared setup and teardown files will affect all tests in the compatibility test. + ## Codegen Codegen is a helpful Playwright feature for generating most of the E2E test code for you. @@ -54,7 +82,6 @@ It essentially records your interactions with the browser and generates the code When you generate tests with `--codegen`, they will be generated with the URLs you visited during the recording, eg: - #### How Codegen generates it: ```js diff --git a/docs/custom-tests/02-tagging-tests.md b/docs/custom-tests/02-tagging-tests.md index a6969be..8b7b8ff 100644 --- a/docs/custom-tests/02-tagging-tests.md +++ b/docs/custom-tests/02-tagging-tests.md @@ -6,9 +6,11 @@ The custom E2E tests feature is available as early-access. ## Introduction -You can use test tags to run specific tests from a plugin/theme. +You can publish your tests to QIT so that other developers can use it to run compatibility tests with their own extensions. -Each extension can have one or multiple test tags, and we also offer some generic tests that can be used by any plugin/theme. +Similarly, you can run other developers' tests to ensure that your extension is compatible with theirs. + +One plugin can have multiple test tags, which can be used to run different sets of tests. ## Listing available test tags diff --git a/docs/custom-tests/03-running-tests.md b/docs/custom-tests/03-running-tests.md index 0b232b5..d1c95cd 100644 --- a/docs/custom-tests/03-running-tests.md +++ b/docs/custom-tests/03-running-tests.md @@ -27,7 +27,7 @@ Replace "example-plugin" with the slug of an extension you own. ## Using a config file -Place a `qit-env.json` or `qit-env.yml` file in the directory you run `qit run:e2e` from. +Place a `qit.json` or `qit.yml` file in the directory you run `qit run:e2e example-plugin` from. Here's an example of a complex config file: @@ -109,7 +109,7 @@ You can also mimick this entire config file using only runtime parameters. Suppose you are scripting a test run and want to pass everything as parameters: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/.qit/plugins/example-plugin \ +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests --source ~/.qit/plugins/example-plugin \ --wp nightly \ --php-version 8.3 \ --object-cache \ @@ -156,19 +156,19 @@ qit run:e2e example-plugin --plugin https://github.com/woocommerce/example-plugi Directory as `source`: ```qitbash -qit run:e2e qit-the-beaver --source ~/my-plugins/example-plugin +qit run:e2e example-plugin --source ~/my-plugins/example-plugin ``` Zip file as `source`: ```qitbash -qit run:e2e qit-the-beaver --source ~/my-plugins/example-plugin/example-plugin.zip +qit run:e2e example-plugin --source ~/my-plugins/example-plugin/example-plugin.zip ``` URL as `source`: ```qitbash -qit run:e2e qit-the-beaver --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip +qit run:e2e example-plugin --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip ``` @@ -179,25 +179,25 @@ If you have a test that you haven't uploaded yet, you can run it directly: Slug as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests ``` Directory as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin ``` Zip file as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin/build.zip +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests --source ~/my-plugins/example-plugin/build.zip ``` URL as `source`, directory as `test-tags`: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests --source https://github.com/woocommerce/example-plugin/releases/tag/nightly.zip +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests --source https://github.com/woocommerce/example-plugin/releases/tag/nightly.zip ``` ## Using test tags @@ -217,21 +217,21 @@ qit run:e2e example-plugin nightly,foo-feature And you can run a test with a tag from a local directory, file, or URL: ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/example-plugin +qit run:e2e example-plugin nightly,foo-feature --source ~/my-plugins/example-plugin ``` ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source ~/my-plugins/example-plugin/example-plugin.zip +qit run:e2e example-plugin nightly,foo-feature --source ~/my-plugins/example-plugin/example-plugin.zip ``` ```qitbash -qit run:e2e qit-the-beaver nightly,foo-feature --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip +qit run:e2e example-plugin nightly,foo-feature --source https://github.com/woocommerce/example-plugin/releases/tag/example-plugin.zip ``` And even run a local test in the mix: ```qitbash -qit run:e2e qit-the-beaver ~/my-plugins/example-plugin/tests,nightly,foo-feature --source ~/my-plugins/example-plugin +qit run:e2e example-plugin ~/my-plugins/example-plugin/tests,nightly,foo-feature --source ~/my-plugins/example-plugin ``` ## Testing plugins that require a live site diff --git a/docs/custom-tests/04-running-other-plugins-tests.md b/docs/custom-tests/04-running-other-plugins-tests.md deleted file mode 100644 index f099b37..0000000 --- a/docs/custom-tests/04-running-other-plugins-tests.md +++ /dev/null @@ -1,60 +0,0 @@ -# Running tests from other plugins - -:::info -The custom E2E tests feature is available as early-access. -::: - -## Introduction - -You can run tests from other plugins that you have access to. - -This is useful for compatibility testing, or to run tests that are not part of your plugin, such as getting cheap coverage for your own plugin by leveraging tests that are already written. - -## Running a test from another plugin - -To run a test from another plugin, you can use the `--plugin` flag: - -```qitbash -qit run:e2e example-plugin --plugin example-plugin -``` - -In this example, `example-plugin` is the SUT (System-Under-Test), and `example-plugin` is an additional plugin. - -By default, the SUT always runs the bootstrap and test phases. The additional plugin only runs the bootstrap phase. - -You can also run the test phase of the additional plugin by passing a flag: - -```qitbash -qit run:e2e example-plugin --plugin example-plugin:test -``` - -Now the test phases of both plugins are run. This is useful for ensuring that your plugin does not break the expected behavior of other plugins. - -## Discovering available tests - -You can see all the test tags you have access to by running: - -```qitbash -qit tag:list -``` - -This will print a table like this: - -``` -+-----------------------+---------------+--------+ -| Slug | E2E Tests | Type | -+-----------------------+---------------+--------+ -| example-plugin | default | plugin | -| example-plugin | rc, default | plugin | -+-----------------------+---------------+--------+ -``` - -This table shows the available test tags for each plugin. You can use these tags to run specific tests. - -## Compositing tests - -You can run multiple tests by passing a comma-separated list of tags: - -```qitbash -qit run:e2e example-plugin --plugin example-plugin:test:rc,default -``` diff --git a/docs/custom-tests/04-understanding-lifecycle.md b/docs/custom-tests/04-understanding-lifecycle.md new file mode 100644 index 0000000..305763f --- /dev/null +++ b/docs/custom-tests/04-understanding-lifecycle.md @@ -0,0 +1,104 @@ +import CustomTestsDiagram from '@site/src/img/custom-tests-diagram.png'; + +# Understanding the Lifecycle + +:::info +The custom E2E tests feature is available as early-access. +::: + +## Introduction + +The lifecycle of a custom E2E test consists of several phases that ensure the environment is set up correctly, tests are run, and the environment is cleaned up afterward. Understanding the lifecycle is crucial for writing effective tests and ensuring that your plugin is compatible with other plugins. + +## Phases of the Lifecycle + +The lifecycle of a custom E2E test can be broken down into several phases: + +1. **Starting the Environment** +2. **Installing Additional Dependencies** +3. **Shared Setup** +4. **DB Export** +5. **(Foreach plugin) DB Import** +6. **(Foreach plugin) Isolated Setup** +7. **(Foreach plugin) Test Phase** +8. **(Foreach plugin) Teardown Phase** +9. **Shared Teardown** +10. **Post-Processing, reports, etc** + +Any change a plugin does in the shared setup persists for the whole test suite. Any change a plugin does in the isolated setup persists only for the plugin's test suite. + +This progressive structure allows for a systematic approach to testing, especially compatibility tests between plugins. The diagram below illustrates the lifecycle of a custom E2E test: + + + +## Files of the Lifecycle + +The lifecycle is managed through the files inside the `bootstrap` directory. Refer to [Generating Tests](generating-tests) for more information on scaffolding tests. + +## 1. Starting the Environment + +Before diving into the setup phases, the system prepares the testing environment: + +- **Start Environment**: Spins up a docker-based WordPress environment with the necessary PHP version, etc. +- **Download Plugins and Themes**: All necessary plugins and themes are downloaded. +- **Install WordPress**: WordPress is installed within the Docker environment. +- **Activate Plugins**: Plugins are activated. +- **Move Must-Use Plugins**: Any must-use plugins of the plugins under test are moved to the appropriate directory. + +2. Installing Additional Dependencies + +If your tests require additional NPM packages, you can declare them in the `dependencies.json` file. These dependencies are installed before running the tests. This is a JSON array of strings, eg: + +```json +[ + "uuid", + "lodash" +] +``` + +It's preferable to avoid adding dependencies if possible, as they can conflict with other plugins dependencies. + +## 2. Shared Setup Phase + +The **Shared Setup Phase** involves setting up shared resources or configurations that are common across all plugins. This phase ensures that all plugins have access to the same environment and data before running their tests. + +### What to Include in the Shared Setup Phase + +- **Get rid of onboarding wizards**: If your plugin has an onboarding wizard, configure it to prevent it from appearing during tests. +- **Disable Data Consent Forms**: Remove any data consent prompts or initial setup screens. +- **Configure or Mock External Services**: If your plugin integrates with external services, enable a development mode or mock external requests. + +## 3. DB Export and Import + +The DB export and import is handled automatically for you. + +## 4. Isolated Setup Phase + +The **Isolated Setup Phase** is responsible for setting up the environment specific to each plugin before running its tests. This phase ensures that each plugin has a clean slate to work with and doesn't interfere with other plugins' tests. + +### What to Include in the Isolated Setup Phase + +- **Install Themes**: If your tests require a specific theme, **install** it during this phase so it’s available during the Test Phase. +- **Activate Plugins**: Activate the plugin you are testing. +- **Customize WordPress Settings**: Configure WordPress settings specific to your plugin's tests. +- **Add Test Data**: Insert any test data or configurations required for your plugin's tests. + +## 5. Test Phase + +The **Test Phase** is where the actual testing happens. This is where you interact with the browser, verify your plugin's functionality, and check for any compatibility issues with other plugins. + +## 6. Teardown Phase + +The **Teardown Phase** runs after your tests are completed. You can use it to clean up any resources or configurations set during the setup phase. + +### What to Include in the Teardown Phase + +- **Reset Mock Services**: Reset any mocks or stubs used for external services. + +## 7. Shared Teardown +After all plugin tests are completed, the **Shared Teardown** phase cleans up any shared resources or configurations set during the Shared Setup phase. + +## Environment Variables +You can use environment variables in your tests to pass secrets or configurations without hardcoding them.Refer to the [Environment Variables](https://chatgpt.com/docs/environment/environment-variables) documentation for more information. + +By structuring your documentation in this progressive manner, readers can build their understanding step by step. Starting with the basic setup and teardown processes, and then introducing shared setup and teardown concepts, allows users to grasp the foundational elements before moving on to more complex configurations.If you need further assistance or have any questions about implementing these phases, feel free to ask! \ No newline at end of file diff --git a/docs/custom-tests/05-bootstrap-and-test-phases.md b/docs/custom-tests/05-bootstrap-and-test-phases.md deleted file mode 100644 index 4b64a62..0000000 --- a/docs/custom-tests/05-bootstrap-and-test-phases.md +++ /dev/null @@ -1,145 +0,0 @@ -import CustomTestsDiagram from '@site/src/img/custom-tests-diagram.png'; -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -# Bootstrap and Test Phases -The custom E2E tests feature is available as early-access. -## Introduction -The E2E Tests are structured to ensure that each plugin is tested in a clean environment while efficiently managing shared resources. The key phases are: -1. **Preparation Phase** -2. **Setup Phase** -3. **Teardown Phase** -4. **Shared Setup** -5. **Shared Teardown** -6. **Post-Processing**This progressive structure allows for a systematic approach to testing, starting from individual plugin setups to shared configurations.Here's the flow of execution: -## The Preparation Phase -Before diving into the setup phases, the system prepares the testing environment: -- **Start Environment**: The Tester initiates the process. -- **Download Plugins and Themes**: All necessary plugins and themes are downloaded. -- **Start Docker Environment**: A Docker environment is initialized to ensure isolation. -- **Install WordPress**: WordPress is installed within the Docker environment. -- **Activate Plugins**: Plugins are activated. -- **Move Must-Use Plugins**: Any must-use plugins are moved to the appropriate directory. - - -## 1. Setup Phase -In the **Setup Phase**, you prepare everything your tests need and perform the initial setup of your plugin. This phase is specific to each plugin and ensures that any plugin-specific configurations are in place before the tests run. -### What to Include in the Setup Phase - -- **Configure Onboarding Wizards**: If your plugin has an onboarding wizard, configure it to prevent it from appearing during tests. -- **Disable Data Consent Forms**: Remove any data consent prompts or initial setup screens. -- **Mock External Services**: If your plugin integrates with external services, set up mock responses or enable a development mode. -- **Install Themes**: If your tests require a specific theme, **install** it during this phase so it’s available during the Test Phase. -### Setup Files -You can use the following files in your setup phase: -#### `bootstrap.sh` - -- A bash script that, if present, will be executed. -- Use `wp` (WP-CLI) commands and bash scripting to set up your environment.**Example:** -#### `bootstrap.php` - -- A PHP file that, if present, will be executed. -- Note: WordPress is **not loaded** in the context of this file. -#### `mu-plugin.php` - -- A must-use plugin file that, if present, will be copied to the `wp-content/mu-plugins` directory. -- This file runs on **all requests** during the E2E test. -- WordPress **is loaded** in the context of this file. -- For logic that should run only once, set a flag to prevent multiple executions. -### Where to Place the Setup Files -Place your setup files in the `bootstrap` directory within your E2E test suite:**Note:** You can organize your tests in any way that suits your project structure. - - -## 2. Teardown Phase -After your tests have run, the **Teardown Phase** is responsible for cleaning up any changes made during the Setup and Test Phases. This ensures that the environment is reset and ready for the next set of tests. -### What to Include in the Teardown Phase - -- **Deactivate Plugins**: Deactivate any plugins activated during setup. -- **Remove Test Data**: Delete any test data or configurations added during testing. -- **Reset Mock Services**: Reset any mocks or stubs used for external services. -### Teardown Files -You can use the following files in your teardown phase: -#### `teardown.sh` - -- A bash script that, if present, will be executed. -- Use `wp` (WP-CLI) commands and bash scripting to clean up your environment. -#### `teardown.php` - -- A PHP file that, if present, will be executed. -- Note: WordPress is **not loaded** in the context of this file. -#### `mu-plugin.php` - -- A must-use plugin file for teardown, if needed. -- Place any teardown logic that needs to run on all requests here. -- Remember to set flags to prevent multiple executions if necessary. -### Where to Place the Teardown Files -Place your teardown files in a `teardown` directory within your E2E test suite: - - -## 3. Shared Setup -The **Shared Setup** phase involves running setup scripts that are common across all plugins. This phase is useful for setting up shared dependencies or configurations that multiple plugins might require. -### What to Include in the Shared Setup Phase - -- **Install Shared Themes or Plugins**: Install any themes or plugins that are required by multiple plugins. -- **Configure Global Settings**: Set up WordPress settings that are common across tests. -- **Prepare Shared Data**: Import or generate data that will be used by multiple plugins. -### Shared Setup Files -Place your shared setup scripts in the `shared-setup` directory: -#### `bootstrap.sh` - -- Contains shared bash scripts for setting up the environment. -#### `bootstrap.php` - -- Contains shared PHP scripts for setup. -#### `mu-plugin.php` - -- Shared must-use plugin that runs during all requests. -### Where to Place the Shared Setup Files - - - -## 4. Shared Teardown -After all plugin tests are completed, the **Shared Teardown** phase cleans up any shared resources or configurations set during the Shared Setup phase. -### What to Include in the Shared Teardown Phase - -- **Deactivate Shared Plugins/Themes**: Remove any shared plugins or themes installed. -- **Reset Global Settings**: Revert any global settings to their defaults. -- **Clean Up Shared Data**: Delete any shared data that was created. -### Shared Teardown Files -Place your shared teardown scripts in the `shared-teardown` directory: -#### `teardown.sh` - -- Contains shared bash scripts for cleaning up the environment. -#### `teardown.php` - -- Contains shared PHP scripts for teardown. -#### `mu-plugin.php` - -- Shared must-use plugin for teardown logic. -### Where to Place the Shared Teardown Files - - - -## 5. The Entry Point -The `entrypoint.js` is a file that, if present, will be executed when your **Test Phase** starts. This is an ideal place to perform plugin-specific initializations, such as activating a theme that you have previously installed during the Setup Phase. -### Where to Place the Entry Point -Place the `entrypoint.js` in the root of your E2E test suite: - - -## 6. The Test Phase -This is where the actual testing happens. We utilize Playwright to interact with the browser and verify your plugin's functionality. -### Running Your Tests -By default, only the test phase of the plugin you're running tests from will be executed. -#### E2E Test Command -To run the E2E tests for your plugin without testing others, use:This command will: -- Run the **Setup Phase** and **Teardown Phase** of your plugin. -- Skip the test phases of other plugins. -#### Compatibility Test Command -To run a full compatibility test including other plugins, use:This command will: -- Run the **Shared Setup** and **Shared Teardown** phases. -- Execute the **Setup**, **Test**, and **Teardown** phases for all plugins that have tests published to QIT. - - -## Environment Variables -You can use environment variables in your tests to pass secrets or configurations without hardcoding them.Refer to the [Environment Variables](https://chatgpt.com/docs/environment/environment-variables) documentation for more information. - -By structuring your documentation in this progressive manner, readers can build their understanding step by step. Starting with the basic setup and teardown processes, and then introducing shared setup and teardown concepts, allows users to grasp the foundational elements before moving on to more complex configurations.If you need further assistance or have any questions about implementing these phases, feel free to ask! \ No newline at end of file diff --git a/docs/environment/01-getting-started.md b/docs/environment/01-getting-started.md index 2b02b20..dd06d53 100644 --- a/docs/environment/01-getting-started.md +++ b/docs/environment/01-getting-started.md @@ -63,7 +63,7 @@ This will create an environment with PHP 8.3 on WordPress RC version, with Guten ## Using configuration files -Create a `qit-env.yml` file in your project directory with the following content: +Create a `qit.yml` file in your project directory with the following content: ```yaml wordpress_version: rc diff --git a/docs/environment/02-creating-config-files.md b/docs/environment/02-creating-config-files.md index d700886..8a856b5 100644 --- a/docs/environment/02-creating-config-files.md +++ b/docs/environment/02-creating-config-files.md @@ -13,7 +13,7 @@ In the QIT Local Test Environment, configuration files are a powerful way to pre ### 1. File format - **JSON or YAML**: You can create configuration files in either JSON or YAML format. -- **Naming**: Name your file `qit-env.json` or `qit-env.yml`. For overrides, use `qit-env.override.json` or `qit-env.override.yml`. +- **Naming**: Name your file `qit.json` or `qit.yml`. For overrides, use `qit.override.json` or `qit.override.yml`. ### 2. Configuration options diff --git a/docs/environment/04-installing-plugins-other-sources.md b/docs/environment/04-installing-plugins-other-sources.md index 2fa032d..e5f28e2 100644 --- a/docs/environment/04-installing-plugins-other-sources.md +++ b/docs/environment/04-installing-plugins-other-sources.md @@ -32,7 +32,7 @@ We assume for the purposes of simplicity that the GitHub pepository is a WordPre Example command: `qit env:up --requires=public-handler.php --plugins=my-public-plugin` -Or just `qit env:up` if you have this `qit-env.yml` file: +Or just `qit env:up` if you have this `qit.yml` file: ```yaml plugins: @@ -91,7 +91,7 @@ This example is similar to the previous one, but it assumes that the GitHub repo Example command: `qit env:up --requires=private-handler.php --plugins=my-private-plugin` -Or just `qit env:up` if you have this `qit-env.yml` file: +Or just `qit env:up` if you have this `qit.yml` file: ```yaml plugins: @@ -172,7 +172,7 @@ You can get really creative with custom handlers. In this example, we will: Example command: `qit env:up --requires=advanced-handler.php --plugins=my-advanced-plugin` -Or just `qit env:up` if you have this `qit-env.yml` file: +Or just `qit env:up` if you have this `qit.yml` file: ```yaml plugins: @@ -349,7 +349,7 @@ requires: You can use multiple custom handlers by including them in your config files, or at runtime with the `--requires` option in the QIT command. For example: -`qit-env.yml` +`qit.yml` ```yaml plugins: diff --git a/src/img/custom-tests-diagram.png b/src/img/custom-tests-diagram.png index 6ec1be9c2340c8498962b1392b4dcd0b3c883cc9..79f8140e15d730a743e94dd3130c27b05cb47e27 100644 GIT binary patch literal 47947 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 Date: Mon, 25 Nov 2024 10:02:23 -0300 Subject: [PATCH 3/3] Tweak --- docs/custom-tests/04-understanding-lifecycle.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/custom-tests/04-understanding-lifecycle.md b/docs/custom-tests/04-understanding-lifecycle.md index 305763f..e37ad05 100644 --- a/docs/custom-tests/04-understanding-lifecycle.md +++ b/docs/custom-tests/04-understanding-lifecycle.md @@ -18,10 +18,10 @@ The lifecycle of a custom E2E test can be broken down into several phases: 2. **Installing Additional Dependencies** 3. **Shared Setup** 4. **DB Export** -5. **(Foreach plugin) DB Import** -6. **(Foreach plugin) Isolated Setup** -7. **(Foreach plugin) Test Phase** -8. **(Foreach plugin) Teardown Phase** +5. **DB Import (foreach plugin)** +6. **Isolated Setup (foreach plugin)** +7. **Test Phase (foreach plugin)** +8. **Teardown Phase (foreach plugin)** 9. **Shared Teardown** 10. **Post-Processing, reports, etc**