diff --git a/.bunnyshell/docker/php/Dockerfile b/.bunnyshell/docker/php/Dockerfile
index 06f13595c9..fff612c6d2 100644
--- a/.bunnyshell/docker/php/Dockerfile
+++ b/.bunnyshell/docker/php/Dockerfile
@@ -6,6 +6,7 @@ ARG NODE_VERSION=20
ARG ALPINE_VERSION=3.18
ARG COMPOSER_VERSION=2.6
ARG PHP_EXTENSION_INSTALLER_VERSION=latest
+ARG DATABASE_URL
FROM composer:${COMPOSER_VERSION} AS composer
@@ -13,6 +14,8 @@ FROM mlocati/php-extension-installer:${PHP_EXTENSION_INSTALLER_VERSION} AS php_e
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS base
+ENV DATABASE_URL=${DATABASE_URL}
+
# persistent / runtime deps
RUN apk add --no-cache \
acl \
@@ -89,20 +92,23 @@ RUN set -eux; \
g++ \
gcc \
make \
+ git \
;
# prevent the reinstallation of vendors at every changes in the source code
-COPY package.json yarn.* ./
-RUN set -eux; \
- yarn install; \
- yarn cache clean
+COPY package.json package-*.json ./
COPY --from=base /srv/sylius/src/Sylius/Bundle/UiBundle/Resources/private src/Sylius/Bundle/UiBundle/Resources/private/
-COPY --from=base /srv/sylius/src/Sylius/Bundle/AdminBundle/Resources/private src/Sylius/Bundle/AdminBundle/Resources/private/
+COPY --from=base /srv/sylius/src/Sylius/Bundle/AdminBundle src/Sylius/Bundle/AdminBundle/
COPY --from=base /srv/sylius/src/Sylius/Bundle/ShopBundle/Resources/private src/Sylius/Bundle/ShopBundle/Resources/private/
+COPY --from=base /srv/sylius/vendor/symfony/ux-autocomplete/assets vendor/symfony/ux-autocomplete/assets/
+COPY --from=base /srv/sylius/vendor/symfony/ux-live-component/assets vendor/symfony/ux-live-component/assets/
+
+RUN set -eux; \
+ npm install;
COPY webpack.config.js ./
-RUN yarn build:prod
+RUN npm run build:prod
FROM base AS sylius_php_prod
diff --git a/.bunnyshell/templates/preview/bunnyshell.yaml b/.bunnyshell/templates/preview/bunnyshell.yaml
index 94b32cbff0..ab45339670 100644
--- a/.bunnyshell/templates/preview/bunnyshell.yaml
+++ b/.bunnyshell/templates/preview/bunnyshell.yaml
@@ -43,6 +43,8 @@ components:
context: .
dockerfile: .bunnyshell/docker/php/Dockerfile
target: sylius_php_prod
+ args:
+ DATABASE_URL: 'mysql://{{ env.vars.MYSQL_USER }}:{{ env.vars.MYSQL_PASSWORD }}@database/{{ env.vars.MYSQL_DATABASE }}?serverVersion=8.0'
command: php-fpm
entrypoint: /usr/local/bin/php-entrypoint
environment:
diff --git a/composer-require-checker.json b/composer-require-checker.json
index 2643132571..b4c8f81b7a 100644
--- a/composer-require-checker.json
+++ b/composer-require-checker.json
@@ -89,6 +89,7 @@
"Psr\\Container\\ContainerInterface",
"Psr\\Http\\Message\\RequestFactoryInterface",
"Psr\\Http\\Message\\StreamFactoryInterface",
+ "Sylius\\Bundle\\UiBundle\\Registry\\TemplateBlockRegistryInterface",
"Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface"
],
"php-core-extensions" : [
diff --git a/composer.json b/composer.json
index a9dbaa3c74..4c2d3f7c2d 100644
--- a/composer.json
+++ b/composer.json
@@ -87,11 +87,12 @@
"sylius/resource": "^1.10",
"sylius/resource-bundle": "^1.10",
"sylius/theme-bundle": "^2.3",
+ "sylius/twig-hooks": "~0.2.4",
"symfony/asset": "^6.4.0",
+ "symfony/cache-contracts": "^2.5 || ^3.0",
"symfony/clock": "^6.4.0",
"symfony/config": "^6.4.0",
"symfony/console": "^6.4.1",
- "symfony/cache-contracts": "^2.5 || ^3.0",
"symfony/dependency-injection": "^6.4.1",
"symfony/deprecation-contracts": "^3.1",
"symfony/doctrine-bridge": "^6.4.0",
@@ -125,17 +126,24 @@
"symfony/security-http": "^6.4.0",
"symfony/serializer": "^6.4.0",
"symfony/service-contracts": "^2.5 || ^3.0",
+ "symfony/stimulus-bundle": "^2.12",
"symfony/string": "^6.4.0",
"symfony/templating": "^6.4.0",
"symfony/translation": "^6.4.0",
"symfony/translation-contracts": "^3.3",
"symfony/twig-bundle": "^6.4.0",
+ "symfony/ux-autocomplete": "^2.17",
+ "symfony/ux-live-component": "^2.17",
+ "symfony/ux-twig-component": "^2.17",
"symfony/validator": "^6.4.0",
"symfony/webpack-encore-bundle": "^1.17.1",
"symfony/workflow": "^6.4.0",
"symfony/yaml": "^6.4.0",
- "twig/intl-extra": "^2.12 || ^3.4",
- "twig/twig": "^2.12 || ^3.3",
+ "symfonycasts/dynamic-forms": "v0.1.1",
+ "twig/extra-bundle": "~3.8.0",
+ "twig/intl-extra": "~3.8.0",
+ "twig/string-extra": "~3.8.0",
+ "twig/twig": "~3.8.0",
"webmozart/assert": "^1.9",
"willdurand/hateoas": "^3.0",
"willdurand/hateoas-bundle": "^2.0",
@@ -188,8 +196,7 @@
"conflict": {
"api-platform/core": "2.7.17",
"doctrine/orm": ">= 2.16.0",
- "stof/doctrine-extensions-bundle": "1.8.0",
- "twig/twig": "3.9.0"
+ "stof/doctrine-extensions-bundle": "1.8.0"
},
"require-dev": {
"behat/behat": "^3.6.1",
diff --git a/config/bundles.php b/config/bundles.php
index a721c9c598..34025408e7 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -59,4 +59,10 @@ return [
SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true],
SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true],
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
+ Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
+ Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
+ Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true],
+ Sylius\TwigHooks\TwigHooksBundle::class => ['all' => true],
+ Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true],
+ Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
];
diff --git a/config/packages/_sylius.yaml b/config/packages/_sylius.yaml
index deef9ce200..663f65eff9 100644
--- a/config/packages/_sylius.yaml
+++ b/config/packages/_sylius.yaml
@@ -1,12 +1,12 @@
imports:
- { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" }
- - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" }
-
- { resource: "@SyliusShopBundle/Resources/config/app/config.yml" }
- { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" }
+ - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" }
+
- { resource: "../parameters.yaml" }
parameters:
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
index 8545473ddd..3b315dcc15 100644
--- a/config/packages/twig.yaml
+++ b/config/packages/twig.yaml
@@ -2,11 +2,3 @@ twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
-
-services:
- _defaults:
- public: false
- autowire: true
- autoconfigure: true
-
- Twig\Extra\Intl\IntlExtension: ~
diff --git a/config/routes/ux_live_component.yaml b/config/routes/ux_live_component.yaml
new file mode 100644
index 0000000000..e56523abfb
--- /dev/null
+++ b/config/routes/ux_live_component.yaml
@@ -0,0 +1,5 @@
+live_component:
+ resource: '@LiveComponentBundle/config/routes.php'
+ prefix: '/_components'
+ # adjust prefix to add localization to your components
+ #prefix: '/{_locale}/_components'
diff --git a/features/admin/addressing/managing_countries/adding_country.feature b/features/admin/addressing/managing_countries/adding_country.feature
index 37e5b6a1b7..513893b38d 100644
--- a/features/admin/addressing/managing_countries/adding_country.feature
+++ b/features/admin/addressing/managing_countries/adding_country.feature
@@ -7,7 +7,7 @@ Feature: Adding a new country
Background:
Given I am logged in as an administrator
- @ui @api
+ @api @ui
Scenario: Adding country
When I want to add a new country
And I choose "United States"
diff --git a/features/admin/addressing/managing_countries/adding_country_with_provinces.feature b/features/admin/addressing/managing_countries/adding_country_with_provinces.feature
index 5986d02e2d..ad44751123 100644
--- a/features/admin/addressing/managing_countries/adding_country_with_provinces.feature
+++ b/features/admin/addressing/managing_countries/adding_country_with_provinces.feature
@@ -7,7 +7,7 @@ Feature: Adding countries with provinces
Background:
Given I am logged in as an administrator
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Adding a country with a province
When I want to add a new country
And I choose "United Kingdom"
@@ -17,7 +17,7 @@ Feature: Adding countries with provinces
And the country "United Kingdom" should appear in the store
And the country "United Kingdom" should have the "Scotland" province
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Adding a country with two provinces
When I want to add a new country
And I choose "United Kingdom"
diff --git a/features/admin/addressing/managing_countries/country_validation.feature b/features/admin/addressing/managing_countries/country_validation.feature
index 9815e50c69..b9813ad67c 100644
--- a/features/admin/addressing/managing_countries/country_validation.feature
+++ b/features/admin/addressing/managing_countries/country_validation.feature
@@ -8,7 +8,7 @@ Feature: Country validation
Given the store operates in "Norway"
And I am logged in as an administrator
- @ui @api
+ @api @ui
Scenario: Trying to add a new country with used code
When I want to add a new country
Then I should not be able to choose "Norway"
diff --git a/features/admin/addressing/managing_countries/editing_country.feature b/features/admin/addressing/managing_countries/editing_country.feature
index fe3c162bf3..b65a785917 100644
--- a/features/admin/addressing/managing_countries/editing_country.feature
+++ b/features/admin/addressing/managing_countries/editing_country.feature
@@ -7,7 +7,7 @@ Feature: Editing country
Background:
Given I am logged in as an administrator
- @ui @api
+ @api @ui
Scenario: Disabling country
Given the store has country "United States"
When I want to edit this country
@@ -16,7 +16,7 @@ Feature: Editing country
Then I should be notified that it has been successfully edited
And this country should be disabled
- @ui @api
+ @api @ui
Scenario: Enabling country
Given the store has disabled country "United States"
When I want to edit this country
@@ -25,7 +25,7 @@ Feature: Editing country
Then I should be notified that it has been successfully edited
And this country should be enabled
- @ui @api
+ @api @ui
Scenario: Seeing disabled code field while editing country
Given the store has country "United States"
When I want to edit this country
diff --git a/features/admin/addressing/managing_countries/managing_provinces_of_country.feature b/features/admin/addressing/managing_countries/managing_provinces_of_country.feature
index 54e48630db..cc143c7cf0 100644
--- a/features/admin/addressing/managing_countries/managing_provinces_of_country.feature
+++ b/features/admin/addressing/managing_countries/managing_provinces_of_country.feature
@@ -8,7 +8,7 @@ Feature: Managing provinces of a country
Given the store has country "United Kingdom"
And I am logged in as an administrator
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Adding a province to an existing country
When I want to edit this country
And I add the "Scotland" province with "GB-SCT" code
@@ -16,7 +16,7 @@ Feature: Managing provinces of a country
Then I should be notified that it has been successfully edited
And this country should have the "Scotland" province
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Removing a province from an existing country
Given this country has the "Northern Ireland" province with "GB-NIR" code
When I want to edit this country
@@ -25,7 +25,7 @@ Feature: Managing provinces of a country
Then I should be notified that it has been successfully edited
And this country should not have the "Northern Ireland" province
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Removing a province that is a zone member should not be possible
Given this country has the "Northern Ireland" province with "GB-NIR" code
And this country also has the "Scotland" province with "GB-SCT" code
@@ -43,7 +43,7 @@ Feature: Managing provinces of a country
And this country should still have the "Scotland" province
And this country should still have the "England" province
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Removing a province that is not a zone member anymore should be possible
Given this country has the "Northern Ireland" province with "GB-NIR" code
And this country also has the "Scotland" province with "GB-SCT" code
@@ -60,18 +60,18 @@ Feature: Managing provinces of a country
And this country should not have the "England" province
And this country should still have the "Northern Ireland" and "Scotland" provinces
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Removing and adding a new province to an existing country
Given this country has the "Northern Ireland" province with "GB-NIR" code
When I want to edit this country
- And I delete the "Northern Ireland" province of this country
And I add the "Scotland" province with "GB-SCT" code
+ And I delete the "Northern Ireland" province of this country
And I save my changes
Then I should be notified that it has been successfully edited
And this country should not have the "Northern Ireland" province
And this country should have the "Scotland" province
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Adding a province with an austrian province code
When I want to edit this country
And I add the "Wien" province with "AT-9" code
diff --git a/features/admin/addressing/managing_countries/province_unique_fields_validation.feature b/features/admin/addressing/managing_countries/province_unique_fields_validation.feature
index 6c10b40638..51bc65c210 100644
--- a/features/admin/addressing/managing_countries/province_unique_fields_validation.feature
+++ b/features/admin/addressing/managing_countries/province_unique_fields_validation.feature
@@ -9,7 +9,7 @@ Feature: Province unique fields validation
And this country has the "Northern Ireland" province with "GB-NIR" code
And I am logged in as an administrator
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add a new province with a taken code
When I want to add a new country
And I choose "Gibraltar"
@@ -17,14 +17,14 @@ Feature: Province unique fields validation
And I try to add it
Then I should be notified that province code must be unique
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add a new province with a taken name
When I want to edit this country
And I add the "Northern Ireland" province with "GB-NI" code
And I save my changes
Then I should be notified that province name must be unique
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add new provinces with duplicated codes
When I want to edit this country
And I add the "Scotland" province with "GB-SCO" code
@@ -32,7 +32,7 @@ Feature: Province unique fields validation
And I save my changes
Then I should be notified that all province codes and names within this country need to be unique
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add new provinces with duplicated names
When I want to edit this country
And I add the "Scotland" province with "GB-SC" code
diff --git a/features/admin/addressing/managing_countries/province_validation.feature b/features/admin/addressing/managing_countries/province_validation.feature
index 9f9567157b..d064c157a1 100644
--- a/features/admin/addressing/managing_countries/province_validation.feature
+++ b/features/admin/addressing/managing_countries/province_validation.feature
@@ -8,7 +8,7 @@ Feature: Province validation
Given the store has country "United Kingdom"
And I am logged in as an administrator
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add a new province without specifying its code
When I want to create a new province in country "United Kingdom"
And I name the province "Scotland"
@@ -17,7 +17,7 @@ Feature: Province validation
Then I should be notified that code is required
And province with name "Scotland" should not be added in this country
- @ui @mink:chromedriver @api
+ @api @ui @mink:chromedriver
Scenario: Trying to add a new province with a too long code
When I want to create a new province in country "United Kingdom"
And I name the province "Scotland"
@@ -25,7 +25,7 @@ Feature: Province validation
And I try to save my changes
Then I should be informed that the provided province code is too long
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to add a new province without specifying its name
When I want to create a new province in country "United Kingdom"
And I specify the province code as "GB-SCT"
@@ -34,7 +34,7 @@ Feature: Province validation
Then I should be notified that name is required
And province with code "GB-SCT" should not be added in this country
- @ui @javascript @api
+ @api @ui @javascript
Scenario: Trying to remove name from an existing province
Given this country has the "Northern Ireland" province with "GB-NIR" code
When I want to edit this country
diff --git a/features/admin/addressing/managing_zones/adding_zone.feature b/features/admin/addressing/managing_zones/adding_zone.feature
index 75c2020553..3ceaec5580 100644
--- a/features/admin/addressing/managing_zones/adding_zone.feature
+++ b/features/admin/addressing/managing_zones/adding_zone.feature
@@ -12,7 +12,7 @@ Feature: Adding a new zone with country type members
And the store has a zone "North America" with code "NA"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a zone with a country type member
When I want to create a new zone consisting of country
And I name it "European Union"
@@ -32,7 +32,7 @@ Feature: Adding a new zone with country type members
Then I should be notified that it has been successfully created
And the zone named "United States" with the "Alabama" province member should appear in the registry
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a zone with zone type member
When I want to create a new zone consisting of zone
And I name it "America"
@@ -51,7 +51,7 @@ Feature: Adding a new zone with country type members
And I add it
Then I should be informed that the provided zone member code is too long
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a zone with a country type member and a shipping scope
When I want to create a new zone consisting of country
And I name it "European Union"
@@ -63,7 +63,7 @@ Feature: Adding a new zone with country type members
And the zone named "European Union" with the "France" country member should appear in the registry
And its scope should be "shipping"
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding zone with disabled country
When I want to create a new zone consisting of country
And I name it "European Union"
diff --git a/features/admin/addressing/managing_zones/deleting_zone.feature b/features/admin/addressing/managing_zones/deleting_zone.feature
index 8b55f202c6..1d61d33416 100644
--- a/features/admin/addressing/managing_zones/deleting_zone.feature
+++ b/features/admin/addressing/managing_zones/deleting_zone.feature
@@ -23,7 +23,7 @@ Feature: Deleting a zone
@ui @api
Scenario: Deleting zone with associated tax rates should not be possible
When I try to delete the zone named "South America"
- Then I should be notified that the zone is in use and cannot be deleted
+ Then I should be notified that this zone cannot be deleted
And I should still see the zone named "South America" in the list
@ui @api
diff --git a/features/admin/addressing/managing_zones/editing_zone.feature b/features/admin/addressing/managing_zones/editing_zone.feature
index b5215e73cb..121eb2e6cb 100644
--- a/features/admin/addressing/managing_zones/editing_zone.feature
+++ b/features/admin/addressing/managing_zones/editing_zone.feature
@@ -14,7 +14,7 @@ Feature: Editing a zone
And the store has a zone "South America" with code "SA"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing a country from a zone
Given the store has a zone "European Union" with code "EU"
And it has the "France" country member
@@ -25,7 +25,7 @@ Feature: Editing a zone
Then I should be notified that it has been successfully edited
And this zone should have only the "France" country member
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing and adding countries to a zone
Given the store has a zone "European Union" with code "EU"
And it has the "Belgium", "France" and "Germany" country members
@@ -36,7 +36,7 @@ Feature: Editing a zone
Then I should be notified that it has been successfully edited
And this zone should have only the "France" country member
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing a province from a zone
Given the store has a zone "United States" with code "USA"
And it has the "Alabama" province member
@@ -47,7 +47,7 @@ Feature: Editing a zone
Then I should be notified that it has been successfully edited
And this zone should have only the "Alabama" province member
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing a zone from a zone
Given the store has a zone "America" with code "AM"
And it has the zone named "North America"
diff --git a/features/admin/addressing/managing_zones/zone_validation.feature b/features/admin/addressing/managing_zones/zone_validation.feature
index 5a1ce21f69..06f1f5e8ce 100644
--- a/features/admin/addressing/managing_zones/zone_validation.feature
+++ b/features/admin/addressing/managing_zones/zone_validation.feature
@@ -52,19 +52,19 @@ Feature: Zone validation
When I want to modify the zone named "European Union"
Then I should not be able to edit its code
- @ui @api
+ @ui @api @mink:chromedriver
Scenario: Being unable to add itself to members during editing an existing zone
Given the store has a zone "European Union" with code "EU"
When I want to modify the zone named "European Union"
- Then I can not add a zone "European Union"
+ Then I should not be able to add the "European Union" zone as a member
- @ui
+ @ui @todo-api
Scenario: Seeing a disabled type field when adding country type zone
When I want to create a new zone consisting of country
Then I should not be able to edit its type
And it should be of country type
- @ui
+ @ui @todo-api
Scenario: Seeing a disabled type field when adding province type zone
When I want to create a new zone consisting of province
Then I should not be able to edit its type
diff --git a/features/admin/being_redirected_to_previous_filtered_page.feature b/features/admin/being_redirected_to_previous_filtered_page.feature
index c75a1e5e0f..acf4b6bfd7 100644
--- a/features/admin/being_redirected_to_previous_filtered_page.feature
+++ b/features/admin/being_redirected_to_previous_filtered_page.feature
@@ -12,7 +12,7 @@ Feature: Being redirected to previous filtered page
And the store has a product "Znicz Pruszków T-Shirt"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being redirected to previous filtered page after deleting a product
When I browse products
And I choose enabled filter
@@ -20,7 +20,7 @@ Feature: Being redirected to previous filtered page
And I delete the "FC Barcelona T-Shirt" product on filtered page
Then I should be redirected to the previous page of only enabled products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being redirected to previous filtered page after cancelling editing a product
When I browse products
And I choose enabled filter
@@ -29,7 +29,7 @@ Feature: Being redirected to previous filtered page
And I cancel my changes
Then I should be redirected to the previous page of only enabled products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being redirected to previous filtered page with pagination after cancelling editing a product
When I browse products
And I choose enabled filter
@@ -39,7 +39,7 @@ Feature: Being redirected to previous filtered page
And I cancel my changes
Then I should be redirected to the 2nd page of only enabled products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being redirected to previous filtered page after cancelling creating a new product
When I browse products
And I choose enabled filter
diff --git a/features/admin/blocking_login_for_disabled_administrators.feature b/features/admin/blocking_login_for_disabled_administrators.feature
index 584ffa8cdc..9d332cafe3 100644
--- a/features/admin/blocking_login_for_disabled_administrators.feature
+++ b/features/admin/blocking_login_for_disabled_administrators.feature
@@ -8,7 +8,7 @@ Feature: Blocking login for disabled administrators
Given the store operates on a single channel in "United States"
And there is an administrator "admin@example.com" identified by "sylius"
- @ui @api
+ @todo @ui @api
Scenario: Sign in with email and password
Given this administrator account is disabled
And I want to log in
@@ -17,7 +17,7 @@ Feature: Blocking login for disabled administrators
And I log in
Then I should not be logged in
- @ui @api
+ @todo @ui @api
Scenario: Revoking the access while administrator is logged in
Given I am logged in as "admin@example.com" administrator
When this administrator account becomes disabled
diff --git a/features/admin/browsing_administration_panel_in_proper_language.feature b/features/admin/browsing_administration_panel_in_proper_language.feature
index 105801348e..69391451da 100644
--- a/features/admin/browsing_administration_panel_in_proper_language.feature
+++ b/features/admin/browsing_administration_panel_in_proper_language.feature
@@ -11,14 +11,14 @@ Feature: Browsing administration panel in a proper locale
And I am logged in as an administrator
And I am using "Polish (Poland)" locale for my panel
- @ui
+ @todo @ui
Scenario: Getting errors in my language
Given I am editing my details
When I change its email to "wrong-email"
And I save my changes
Then I should be notified that this email is not valid in "Polish (Poland)" locale
- @ui
+ @todo @ui
Scenario: Seeing menu in my language
When I open administration dashboard
Then I should see sidebar catalog section configuration in "Polish (Poland)" locale
diff --git a/features/admin/channel/managing_channels/browsing_channels.feature b/features/admin/channel/managing_channels/browsing_channels.feature
index 070993551b..6e86bf99e7 100644
--- a/features/admin/channel/managing_channels/browsing_channels.feature
+++ b/features/admin/channel/managing_channels/browsing_channels.feature
@@ -9,7 +9,7 @@ Feature: Browsing channels
And the store operates on another channel named "Mobile Channel"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Browsing defined channels
When I want to browse channels
Then I should see 2 channels in the list
diff --git a/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature b/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature
index bd44a3db81..8ac94e83ac 100644
--- a/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature
+++ b/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature
@@ -8,7 +8,7 @@ Feature: Choosing a required address in the checkout for a channel
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @ui
+ @api @ui @mink:chromedriver
Scenario: Adding a new channel with a required address in the checkout
When I want to create a new channel
And I specify its code as "MOBILE"
@@ -22,7 +22,7 @@ Feature: Choosing a required address in the checkout for a channel
Then I should be notified that it has been successfully created
And the required address in the checkout for this channel should be shipping
- @api @ui
+ @api @ui @mink:chromedriver
Scenario: Changing a required address in the checkout for an existing channel
Given the store operates on a channel named "Web Store"
When I want to modify this channel
diff --git a/features/admin/channel/managing_channels/deleting_channel.feature b/features/admin/channel/managing_channels/deleting_channel.feature
index fb2976984b..727561480f 100644
--- a/features/admin/channel/managing_channels/deleting_channel.feature
+++ b/features/admin/channel/managing_channels/deleting_channel.feature
@@ -9,7 +9,7 @@ Feature: Deleting a channel
And the store operates on another channel named "Mobile Store"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Deleted channel should disappear from the registry
When I delete channel "Web Store"
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/channel/managing_channels/deleting_multiple_channels.feature b/features/admin/channel/managing_channels/deleting_multiple_channels.feature
index 5346dc8041..7cef25afa2 100644
--- a/features/admin/channel/managing_channels/deleting_multiple_channels.feature
+++ b/features/admin/channel/managing_channels/deleting_multiple_channels.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple channels
And the store operates on another channel named "DE Store"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple channels at once
When I browse channels
And I check the "PL Store" channel
diff --git a/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature b/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature
index 97bc83dfe4..e1396a5e6e 100644
--- a/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature
+++ b/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature
@@ -11,7 +11,7 @@ Feature: Editing menu taxon on channel
And channel "Web Store" has menu taxon "Clothes"
And I am logged in as an administrator
- @todo @api @ui @javascript
+ @todo @api @ui @mink:chromedriver
Scenario: Editing menu taxon on the channel
When I want to modify a channel "Web Store"
And I change its menu taxon to "Guns"
diff --git a/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature b/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature
index 1c5641c89b..dde0b927fa 100644
--- a/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature
+++ b/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature
@@ -9,7 +9,7 @@ Feature: Excluding chosen taxons from displaying the lowest price of discounted
And the store classifies its products as "T-Shirts", "Caps" and "Sweaters"
And I am logged in as an administrator
- @no-api @ui @javascript
+ @no-api @ui @mink:chromedriver
Scenario: Excluding a singular taxon from displaying the lowest price of discounted products
When I want to modify a channel "Poland"
And I exclude the "T-Shirts" taxon from showing the lowest price of discounted products
diff --git a/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature b/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature
index f46c66cb40..575a75bce6 100644
--- a/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature
+++ b/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature
@@ -8,7 +8,7 @@ Feature: Not being able to delete a last available channel
Given the store operates on a channel named "Web Store"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Preventing from deleting only channel
When I delete channel "Web Store"
Then I should be notified that it cannot be deleted
diff --git a/features/admin/channel/theming/managing_themes_per_channel.feature b/features/admin/channel/theming/managing_themes_per_channel.feature
index 2d67624818..25bfea6d60 100644
--- a/features/admin/channel/theming/managing_themes_per_channel.feature
+++ b/features/admin/channel/theming/managing_themes_per_channel.feature
@@ -9,7 +9,7 @@ Feature: Managing themes per channel
And the store has "maverick/meerkat" theme
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: None of the themes are used by default
When I create a new channel "Poland"
Then that channel should not use any theme
diff --git a/features/admin/currency/managing_currencies/adding_currency.feature b/features/admin/currency/managing_currencies/adding_currency.feature
index 02c1d63e7c..bc6bf683f8 100644
--- a/features/admin/currency/managing_currencies/adding_currency.feature
+++ b/features/admin/currency/managing_currencies/adding_currency.feature
@@ -7,7 +7,7 @@ Feature: Adding a new currency
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new currency
When I want to add a new currency
And I choose "Euro"
diff --git a/features/admin/currency/managing_currencies/browsing_currencies.feature b/features/admin/currency/managing_currencies/browsing_currencies.feature
index 52c15f613e..2f0d23a0b3 100644
--- a/features/admin/currency/managing_currencies/browsing_currencies.feature
+++ b/features/admin/currency/managing_currencies/browsing_currencies.feature
@@ -8,7 +8,7 @@ Feature: Browsing currencies
Given the store has currency "Euro", "British Pound"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing currencies in store
When I want to browse currencies of the store
Then I should see 2 currencies in the list
diff --git a/features/admin/currency/managing_currencies/currency_unique_code_validation.feature b/features/admin/currency/managing_currencies/currency_unique_code_validation.feature
index f9049e36a3..bb0bda4ccb 100644
--- a/features/admin/currency/managing_currencies/currency_unique_code_validation.feature
+++ b/features/admin/currency/managing_currencies/currency_unique_code_validation.feature
@@ -8,7 +8,7 @@ Feature: Currency unique code validation
Given the store has currency "Euro"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add currency with taken code
When I want to add a new currency
And I choose "Euro"
diff --git a/features/admin/currency/managing_currencies/editing_currency.feature b/features/admin/currency/managing_currencies/editing_currency.feature
index 060be02b8a..37934d7e0e 100644
--- a/features/admin/currency/managing_currencies/editing_currency.feature
+++ b/features/admin/currency/managing_currencies/editing_currency.feature
@@ -7,7 +7,7 @@ Feature: Editing a currency
Background:
Given I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled code field while editing currency
Given the store has currency "Euro"
When I want to edit this currency
diff --git a/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature
index 415cb6a198..f992de7e2d 100644
--- a/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature
+++ b/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature
@@ -8,7 +8,7 @@ Feature: Adding a new exchange rate
Given the store has currency "US Dollar" and "British Pound"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new exchange rate
When I want to add a new exchange rate
And I specify its ratio as 1.20
diff --git a/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature b/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature
index 9282b222ee..daa799a791 100644
--- a/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature
+++ b/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature
@@ -10,7 +10,7 @@ Feature: Browsing exchange rates
And the exchange rate of "British Pound" to "Bhutanese Ngultrum" is 2.37
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing store's exchange rates
When I am browsing exchange rates of the store
Then I should see 2 exchange rates on the list
diff --git a/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature
index 4a8651e339..2f5b80fd8f 100644
--- a/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature
+++ b/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature
@@ -8,7 +8,7 @@ Feature: Deleting exchange rates
Given the store has currency "US Dollar", "British Pound" and "Bhutanese Ngultrum"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted exchange rate should disappear from the list
Given the exchange rate of "US Dollar" to "British Pound" is 1.2
When I delete the exchange rate between "US Dollar" and "British Pound"
diff --git a/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature b/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature
index 2594303eb9..bc6f7e61e9 100644
--- a/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature
+++ b/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature
@@ -11,7 +11,7 @@ Feature: Deleting multiple exchange rates
And the exchange rate of "Polish Zloty" to "Euro" is 0.22
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple exchange rates at once
When I browse exchange rates
And I check the exchange rate between "Euro" and "British Pound"
diff --git a/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature
index 2de7ea381b..7b2f42a082 100644
--- a/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature
+++ b/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature
@@ -8,7 +8,7 @@ Feature: Editing exchange rate
Given the store has currency "US Dollar" and "British Pound"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Change exchange rate's ratio
Given the exchange rate of "US Dollar" to "British Pound" is 1.30
And I am editing this exchange rate
@@ -17,7 +17,7 @@ Feature: Editing exchange rate
Then I should be notified that it has been successfully edited
And it should have a ratio of 3.21
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change currencies
Given the exchange rate of "US Dollar" to "British Pound" is 1.30
When I want to edit this exchange rate
diff --git a/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature b/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature
index bc963a76bb..968bbb8601 100644
--- a/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature
+++ b/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature
@@ -8,7 +8,7 @@ Feature: Exchange rate validation
Given the store has currency "US Dollar" and "British Pound"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new exchange rate without ratio
When I want to add a new exchange rate
And I choose "US Dollar" as the source currency
@@ -18,7 +18,7 @@ Feature: Exchange rate validation
Then I should be notified that ratio is required
And the exchange rate between "US Dollar" and "British Pound" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new exchange rate with negative ratio
When I want to add a new exchange rate
And I choose "US Dollar" as the source currency
@@ -28,7 +28,7 @@ Feature: Exchange rate validation
Then I should be notified that the ratio must be greater than zero
And the exchange rate between "US Dollar" and "British Pound" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new exchange rate with same target currency as source
When I want to add a new exchange rate
And I specify its ratio as 1.23
diff --git a/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature b/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature
index 536703841d..e64bc8874e 100644
--- a/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature
+++ b/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature
@@ -11,7 +11,7 @@ Feature: Filtering exchange rates by a currency
And the exchange rate of "Polish Zloty" to "Euro" is 0.22
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering exchange rates by a chosen currency
When I browse exchange rates of the store
And I choose "Euro" as a currency filter
diff --git a/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature b/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature
index 886f43f450..5ced3e9125 100644
--- a/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature
+++ b/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature
@@ -9,7 +9,7 @@ Feature: Inability of adding exchange rates with the same currency pair
And the exchange rate of "Euro" to "British Pound" is 1.2
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Being prevented from adding an exchange rate for the same currency pair
When I want to add a new exchange rate
And I specify its ratio as 3.20
@@ -20,7 +20,7 @@ Feature: Inability of adding exchange rates with the same currency pair
And I should still see one exchange rate on the list
And this exchange rate should have a ratio of 1.2
- @ui @api
+ @todo @ui @api
Scenario: Being prevented from adding an exchange rate for a reversed currency pair
When I want to add a new exchange rate
And I specify its ratio as 3.20
diff --git a/features/admin/inventory/managing_inventory/browsing_inventory.feature b/features/admin/inventory/managing_inventory/browsing_inventory.feature
index db1e3668fa..6fe11d0ca8 100644
--- a/features/admin/inventory/managing_inventory/browsing_inventory.feature
+++ b/features/admin/inventory/managing_inventory/browsing_inventory.feature
@@ -13,12 +13,12 @@ Feature: Browsing inventory
And there are 5 units of product "Iron Maiden T-Shirt" available in the inventory
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Browsing only tracked product variants in the store
When I want to browse inventory
Then I should see only one tracked variant in the list
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being informed about on hand quantity of a product variant
When I want to browse inventory
Then I should see that the "Iron Maiden T-Shirt" variant has 5 quantity on hand
diff --git a/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature b/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature
index a2e2445fe5..aa3fb8d494 100644
--- a/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature
+++ b/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature
@@ -14,7 +14,7 @@ Feature: Filtering inventory by code
And there are 25 units of product "RHCP T-Shirt" available in the inventory
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Filtering tracked product variants by code
When I want to browse inventory
And I filter tracked variants with code containing "iron"
diff --git a/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature b/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature
index 619ed89062..485339a3b6 100644
--- a/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature
+++ b/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature
@@ -14,7 +14,7 @@ Feature: Filtering inventory by name
And there are 25 units of product "RHCP T-Shirt" available in the inventory
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Filtering tracked product variants by name
When I want to browse inventory
And I filter tracked variants with name containing "RHCP"
diff --git a/features/admin/locale/channel_independent_translatable_entities_locales.feature b/features/admin/locale/channel_independent_translatable_entities_locales.feature
index 6d6d22b4b4..a48591c9f0 100644
--- a/features/admin/locale/channel_independent_translatable_entities_locales.feature
+++ b/features/admin/locale/channel_independent_translatable_entities_locales.feature
@@ -10,7 +10,7 @@ Feature: Channel independent translatable entities locales
And it uses the "English (United States)" locale by default
And I am logged in as an administrator
- @ui
+ @todo @ui
Scenario: Using all locales to translate an entity
Given the store has locale "German (Germany)"
When I want to create a new translatable entity
diff --git a/features/admin/locale/managing_locales/adding_locale.feature b/features/admin/locale/managing_locales/adding_locale.feature
index f3921f5672..1359deded4 100644
--- a/features/admin/locale/managing_locales/adding_locale.feature
+++ b/features/admin/locale/managing_locales/adding_locale.feature
@@ -7,7 +7,7 @@ Feature: Adding a new locale
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new locale
When I want to create a new locale
And I choose Norwegian
diff --git a/features/admin/locale/managing_locales/locale_unique_code_validation.feature b/features/admin/locale/managing_locales/locale_unique_code_validation.feature
index 1d6ffe0ba0..58f996bd1a 100644
--- a/features/admin/locale/managing_locales/locale_unique_code_validation.feature
+++ b/features/admin/locale/managing_locales/locale_unique_code_validation.feature
@@ -8,7 +8,7 @@ Feature: Locale unique code validation
Given the store has locale "Norwegian (Norway)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add new locale with used code
When I want to add a new locale
Then I should not be able to choose "Norwegian (Norway)"
diff --git a/features/admin/locale/managing_locales/removing_locale.feature b/features/admin/locale/managing_locales/removing_locale.feature
index 233251437e..941ee53fe4 100644
--- a/features/admin/locale/managing_locales/removing_locale.feature
+++ b/features/admin/locale/managing_locales/removing_locale.feature
@@ -10,7 +10,7 @@ Feature: Removing locales
And it uses the "English (United States)" locale by default
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleting unused locale
Given the store has a product "T-Shirt banana"
And this product is named "Banana T-Shirt with Minions" in the "English (United States)" locale
@@ -19,7 +19,7 @@ Feature: Removing locales
Then I should be informed that locale "Polish (Poland)" has been deleted
And only the "English (United States)" locale should be present in the system
- @ui @api
+ @todo @ui @api
Scenario: Deleting a locale in use
Given the store has a product "T-Shirt banana"
And this product is named "Banana T-Shirt with Minions" in the "English (United States)" locale
diff --git a/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature b/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature
index 510d8a333d..c9090a105d 100644
--- a/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature
+++ b/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature
@@ -14,7 +14,7 @@ Feature: Browsing orders
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Seeing a new order in the list
When I browse orders
Then I should see a single order from customer "john.doe@gmail.com"
diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature
index 0fcc81f916..b764021ffd 100644
--- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature
+++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature
@@ -17,7 +17,7 @@ Feature: Seeing the currency in which all orders have been placed
And there is a customer "Satin" identified by an email "satin@teamlucifer.com" and a password "pswd"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Seeing an order placed in the base currency
Given there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And the customer bought a single "Angel T-Shirt"
diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature
index ad3d2ec463..0f80358f5c 100644
--- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature
+++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature
@@ -17,7 +17,7 @@ Feature: Seeing order's payment amount including all fees
And the customer chose "DHL" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Seeing total payment
When I view the summary of the order "#00000666"
Then it should have 2 items
diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature
index 3d7dbd8726..5834fe0c5f 100644
--- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature
+++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature
@@ -17,7 +17,7 @@ Feature: Seeing orders' total in their currency
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui @api
+ @todo @ui @api
Scenario: List of orders from only one channel
Given I changed my current channel to "United States"
And I have product "Angel T-Shirt" in the cart
@@ -26,7 +26,7 @@ Feature: Seeing orders' total in their currency
And I confirm my order
Then the administrator should see the order with total "$20.00" in order list
- @ui @api
+ @todo @ui @api
Scenario: List of orders from different channels
Given I changed my current channel to "United States"
And I have product "Angel T-Shirt" in the cart
diff --git a/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature b/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature
index 9618ec5bc7..e3eb084dd6 100644
--- a/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature
+++ b/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature
@@ -17,7 +17,7 @@ Feature: Sequential order number generation
And the customer chose "Free" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Verifying that orders has correct numbers
When I browse orders
Then I should see an order with "#000000001" number
diff --git a/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature b/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature
index 4af17fe610..383027202b 100644
--- a/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature
+++ b/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature
@@ -20,13 +20,13 @@ Feature: Sorting orders by their number
And the customer chose "Free" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Orders are sorted by descending numbers by default
When I browse orders
Then I should see an order with "#000000001" number
But the first order should have number "#000000003"
- @ui @api
+ @todo @ui @api
Scenario: Changing the number sorting order
Given I am browsing orders
When I switch the way orders are sorted by number
diff --git a/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature b/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature
index bcb828f2eb..dc4b87d23d 100644
--- a/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature
+++ b/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature
@@ -15,7 +15,7 @@ Feature: Shipments are in the state "ready" after checkout
And the customer chose "Free" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @api @ui
Scenario: Checking shipment state of a placed order
When I view the summary of the order "#00000666"
Then it should have shipment in state "Ready"
diff --git a/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature b/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature
index a697dbe5e6..d783e21246 100644
--- a/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature
+++ b/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature
@@ -15,7 +15,7 @@ Feature: Shipping an order
And the customer chose "Free" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @api @ui
Scenario: Finalizing order's shipment
Given I view the summary of the order "#00000666"
When specify its tracking code as "#00044"
@@ -23,13 +23,13 @@ Feature: Shipping an order
Then I should be notified that the order has been successfully shipped
And it should have shipment in state shipped
- @ui @api
+ @api @ui
Scenario: Unable to finalize shipped order's shipment
Given this order has already been shipped
When I view the summary of the order "#00000666"
Then I should not be able to ship this order
- @ui @api
+ @api @ui
Scenario: Checking the shipment state of a completed order
Given this order has already been shipped
When I browse orders
diff --git a/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature b/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature
index b169b37783..bf5498824d 100644
--- a/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature
+++ b/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature
@@ -24,6 +24,17 @@ Feature: Modifying a customer billing address after an order has been placed
Then I should be notified that it has been successfully edited
And this order should have "Lucifer Morningstar", "Seaside Fwy", "90802", "Los Angeles", "United States" as its billing address
+ @ui @mink:chromedriver @no-api
+ Scenario: Being able to choose only provinces of the selected country
+ Given the store also has country "Poland"
+ And this country has the "Malopolska" province with "ML" code
+ And this country has the "Slaskie" province with "SL" code
+ When I view the summary of the order "#00000001"
+ And I want to modify a customer's billing address of this order
+ And I change the billing country to "Poland"
+ Then I should be able to choose the "Malopolska" province for the billing address
+ And I should be able to choose the "Slaskie" province for the billing address
+
@api @ui
Scenario: Modifying a customer's billing address when a product's price has been changed
Given the product "Suit" changed its price to "$300.00"
diff --git a/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature b/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature
index a28c49c659..7d894271c6 100644
--- a/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature
+++ b/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature
@@ -25,6 +25,17 @@ Feature: Modifying a customer shipping address after an order has been placed
Then I should be notified that it has been successfully edited
And this order should be shipped to "Lucifer Morningstar", "Seaside Fwy", "90802", "Los Angeles", "United States"
+ @ui @mink:chromedriver @no-api
+ Scenario: Being able to choose only provinces of the selected country
+ Given the store also has country "Poland"
+ And this country has the "Malopolska" province with "ML" code
+ And this country has the "Slaskie" province with "SL" code
+ When I view the summary of the order "#00000001"
+ And I want to modify a customer's shipping address of this order
+ And I change the shipping country to "Poland"
+ Then I should be able to choose the "Malopolska" province for the shipping address
+ And I should be able to choose the "Slaskie" province for the shipping address
+
@api @ui
Scenario: Modifying a customer's shipping address when a product's price has been changed
Given the product "Suit" changed its price to "$300.00"
diff --git a/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature b/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature
index a88a25b0a8..2b97a893ff 100644
--- a/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature
+++ b/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature
@@ -10,7 +10,7 @@ Feature: Being unable to see details of a cart
And the customer added "PHP T-Shirt" product to the cart
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Being unable to see the details of a cart
When I try to view the summary of the customer's latest cart
Then I should be informed that the order does not exist
diff --git a/features/admin/order/managing_orders/order_details/seeing_order.feature b/features/admin/order/managing_orders/order_details/seeing_order.feature
index 7c16f57baa..583dd97711 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order.feature
@@ -16,7 +16,7 @@ Feature: Seeing basic information about an order
And the customer chose "Free" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing basic information about an order
When I view the summary of the order "#00000666"
Then it should have been placed by the customer "lucy@teamlucifer.com"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature
index 6dccd07970..73abf338aa 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature
@@ -16,7 +16,7 @@ Feature: Seeing aggregated discounts of an order
And there is a customer "robin.hood@sherwood.com" that placed an order "#00000006"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipping and order promotions, but the shipping promotion is not aggregated in summary's promotion total
Given the customer bought 2 "Longbow" products
And the customer chose "DHL" shipping method to "United States" with "Cash on Delivery" payment
@@ -28,7 +28,7 @@ Feature: Seeing aggregated discounts of an order
And the order's shipping total should be "$5.00"
And the order's total should be "$285.00"
- @api @ui
+ @api @todo @ui
Scenario: Seeing multiple order promotions aggregated in summary
Given there is a promotion "Big order discount"
And it gives "$70.00" discount to every order with quantity at least 3
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature
index 07a5a756a6..0520dc1d11 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature
@@ -20,7 +20,7 @@ Feature: Seeing aggregated taxes of an order
And there is a customer "charles.the.great@medieval.com" that placed an order "#00000001"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing aggregated taxes of products and shipping
Given the customer bought a single "Composite bow"
And the customer chose "DHL" shipping method to "United States" with "Offline" payment
@@ -31,7 +31,7 @@ Feature: Seeing aggregated taxes of an order
And the order's tax total should be "$25.30"
And the order's total should be "$135.30"
- @api @ui
+ @api @todo @ui
Scenario: Seeing aggregated taxes of multiple products from different tax rates and shipping
Given the customer bought a single "Composite bow"
And the customer bought a "Claymore" and a "Bastard sword"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature b/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature
index 49c8c6ee23..6aeb3665f6 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature
@@ -22,7 +22,7 @@ Feature: Seeing the currency an order has been placed in on it's details page
And there is a customer "Satin" identified by an email "satin@teamlucifer.com" and a password "pswd"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: All prices are in the base currency when the client haven't chosen any other
Given there is a customer "satin@teamlucifer.com" that placed an order "#00000666"
And the customer bought a single "Angel T-Shirt"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature b/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature
index 0334feb27f..35505af5df 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature
@@ -15,7 +15,7 @@ Feature: Seeing discounts of an order
And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion discount on order while buying at least 3 items
Given the promotion gives "$15.00" discount to every order with quantity at least 3
And the customer bought 4 "Angel T-Shirt" products
@@ -26,7 +26,7 @@ Feature: Seeing discounts of an order
And the order's promotion discount should be "-$15.00" from "Holiday promotion" promotion
And the order's total should be "$141.00"
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion discount on order's items while buying a product from a promoted taxon
Given the promotion gives "$10.00" off on every product classified as "T-Shirts"
And the customer bought a single "Angel T-Shirt"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature
index d3c3bf7c8d..12e7a95d2a 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature
@@ -23,7 +23,7 @@ Feature: Seeing order item detailed data
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing details of item in one row
Given I view the summary of the order "#00000666"
When I check "Marvel T-Shirt" data
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature
index 5decf0c51f..9cfb987c51 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature
@@ -15,7 +15,7 @@ Feature: Seeing included in price taxes of order items
And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing included in price taxes of order items are not counted in taxes total
Given the customer bought 2 "Winchester M1866" products
And the customer chose "Free" shipping method to "United States" with "Offline" payment
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature
index 5eb3c596bb..13ec31df08 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature
@@ -15,7 +15,7 @@ Feature: Seeing taxes of order items
And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing taxes of order items
Given the customer bought a "PHP T-Shirt" and a "Symfony2 T-Shirt"
And the customer chose "Free" shipping method to "United States" with "Offline" payment
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature b/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature
index 24cc2ca4d1..de41f79d9f 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature
@@ -15,7 +15,7 @@ Feature: Seeing order items with proper names
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing order items with proper names
Given the product "Angel T-Shirt" was renamed to "Devil Cardigan"
And the product "Angel Mug" was renamed to "Devil Glass"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature b/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature
index ca8313c618..00d2eea7f4 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature
@@ -12,7 +12,7 @@ Feature: Placing an order
And there is a customer "sylius@example.com" that placed an order "#00000022"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Verifying that order has new state right after checkout
Given the customer bought 3 "Iron Maiden T-Shirt" products
And the customer chose "Free" shipping method to "United States" with "Offline" payment
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature
index 95d4d9b147..8e41b7a61f 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature
@@ -18,7 +18,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer
And the customer chose "Free" shipping method
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing payment state as paid on orders list
When I browse orders
Then the order "#00000666" should have order payment state "Paid"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature
index fcc8a32250..4b59e914b3 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature
@@ -16,7 +16,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer
And the customer chose "Free" shipping method
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing payment state as paid on orders list
When I browse orders
Then the order "#00000666" should have order payment state "Paid"
@@ -26,7 +26,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer
When I view the summary of the order "#00000666"
Then I should be informed that there are no payments
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing payment state as paid on order's summary
When I view the summary of the order "#00000666"
Then I should be informed that there are no payments
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature
index c97a1e025a..1ee021af6f 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature
@@ -15,18 +15,18 @@ Feature: Seeing shipping states of an order after checkout steps
And the customer chose "Free" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing ready order shipping state
When I browse orders
Then order "#00000666" should have shipment state "ready"
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipped order shipping state
Given this order has already been shipped
When I browse orders
Then order "#00000666" should have shipment state "shipped"
- @api @ui
+ @api @todo @ui
Scenario: Seeing cancelled order shipping state
Given the customer cancelled this order
When I browse orders
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature
index 2d3201e533..e1965adb15 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature
@@ -16,12 +16,12 @@ Feature: Seeing shipping states of an order as shipped if there are no shipments
And the customer chose "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipping state as shipped on orders list
When I browse orders
Then the order "#00000666" should have order shipping state "Shipped"
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipping state as shipped on order's summary
When I view the summary of the order "#00000666"
Then it should have order's shipping state "Shipped"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature
index 12222dd7ee..37710be38d 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature
@@ -14,7 +14,7 @@ Feature: Seeing shipping fees of an order
And the customer bought a single "Angel T-Shirt"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing Free shipping of an order
Given the customer chose "Free" shipping method to "United States" with "Offline" payment
When I view the summary of the order "#00000666"
@@ -24,7 +24,7 @@ Feature: Seeing shipping fees of an order
And the order's shipping total should be "$0.00"
And the order's total should be "$39.00"
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipping fee of an order
Given the customer chose "DHL" shipping method to "United States" with "Offline" payment
When I view the summary of the order "#00000666"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature
index 674116b518..6e841f0fb5 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature
@@ -16,7 +16,7 @@ Feature: Seeing taxes of an order
And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing taxes of order items and shipping
Given the customer bought a single "Symfony2 T-Shirt"
And the customer chose "DHL" shipping method to "United States" with "Offline" payment
@@ -28,7 +28,7 @@ Feature: Seeing taxes of an order
And the order's tax total should be "$34.50"
And the order's total should be "$184.50"
- @api @ui
+ @api @todo @ui
Scenario: Seeing taxes of items and shipping from paid order
Given the customer bought a single "Symfony2 T-Shirt"
And the customer chose "DHL" shipping method to "United States" with "Offline" payment
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature
index 3afdc47704..b939d93ab2 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature
@@ -19,7 +19,7 @@ Feature: Seeing shipping total with applied promotion and taxes
And the customer bought a single "Gryffindor scarf"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing taxes of order items and shipping with applied promotion
Given the customer chose "Owl post" shipping method to "United States" with "Offline" payment
When I view the summary of the order "#00000777"
@@ -30,7 +30,7 @@ Feature: Seeing shipping total with applied promotion and taxes
And the order's tax total should be "$24.15"
And the order's total should be "$129.15"
- @api @ui
+ @api @todo @ui
Scenario: Seeing taxes of order items and multiple shipments with applied promotion
Given the store has "Pigeon post" shipping method with "$16.00" fee within the "US" zone
And shipping method "Pigeon post" belongs to "Shipping Services" tax category
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature b/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature
index 90b6d0e780..2f07c487fb 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature
@@ -17,7 +17,7 @@ Feature: Seeing order with different promotions
And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing prices and discount prices of order item
Given the customer bought 2 "PHP T-Shirt" products
And the customer bought a single "Symfony Mug"
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature b/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature
index 3d87782ae6..cfea540d13 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature
@@ -15,7 +15,7 @@ Feature: Seeing an order with its items
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing order items
When I view the summary of the order "#00000666"
Then it should have 2 items
diff --git a/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature b/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature
index a6c1513e8f..ababb1317c 100644
--- a/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature
@@ -16,7 +16,7 @@ Feature: Seeing an order without shipping address
And the customer chose "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing basic information about an order
When I view the summary of the order "#00000666"
Then it should have been placed by the customer "lucy@teamlucifer.com"
diff --git a/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature b/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature
index eab25f8a0e..82bae88b86 100644
--- a/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature
@@ -19,7 +19,7 @@ Feature: Seeing province created manually on order summary page
And the customer chose "DHL" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing manually definied province on order summary page
When I view the summary of the order "#00000666"
Then I should see "East of England" as province in the shipping address
diff --git a/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature b/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature
index 104606918e..f13811169c 100644
--- a/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature
+++ b/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature
@@ -15,7 +15,7 @@ Feature: Seeing shipment shipping date
And it is "20-02-2020 10:30:05" now
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipped at date
When I view the summary of the order "#00000777"
And I ship this order
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature
index 8e38ba6a20..4c6504be43 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature
@@ -13,7 +13,7 @@ Feature: Filtering orders by a channel
And this customer has also placed an order "#00000003" on a channel "Web-US"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by a chosen channel
When I browse orders
And I choose "Web-EU" as a channel filter
@@ -23,7 +23,7 @@ Feature: Filtering orders by a channel
And I should see an order with "#00000002" number
But I should not see an order with "#00000003" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by an another channel
When I browse orders
And I choose "Web-US" as a channel filter
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature
index e6b39dd5ab..97429d84b3 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature
@@ -12,7 +12,7 @@ Feature: Filtering orders
And this customer has also placed an order "#00000003" at "2016-12-06 10:00"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by date from
When I browse orders
And I specify filter date from as "2016-12-05 08:30"
@@ -22,7 +22,7 @@ Feature: Filtering orders
And I should see an order with "#00000003" number
But I should not see an order with "#00000001" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by date to
When I browse orders
And I specify filter date to as "2016-12-05 09:30"
@@ -32,7 +32,7 @@ Feature: Filtering orders
And I should see an order with "#00000002" number
But I should not see an order with "#00000003" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by date from to
When I browse orders
And I specify filter date from as "2016-12-05 08:30"
@@ -43,7 +43,7 @@ Feature: Filtering orders
But I should not see an order with "#00000001" number
And I should not see an order with "#00000003" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by date from without time
When I browse orders
And I specify filter date from as "2016-12-05"
@@ -54,7 +54,7 @@ Feature: Filtering orders
And I should see an order with "#00000003" number
But I should not see an order with "#00000001" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders placed at midnight or just before midnight
Given this customer has placed an order "#00000004" at "2016-12-10 00:00"
And this customer has also placed an order "#00000005" at "2016-12-11 23:59"
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature
index f998fdf220..646e2ece75 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature
@@ -17,7 +17,7 @@ Feature: Filtering orders by products
And the customer chose "Free" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api @javascript
+ @todo @ui @api @javascript
Scenario: Filtering orders by product
When I browse orders
And I filter by product "Galaxy T-Shirt"
@@ -25,7 +25,7 @@ Feature: Filtering orders by products
And I should see an order with "#0000001" number
And I should see an order with "#0000003" number
- @ui @api @mink:chromedriver
+ @todo @ui @api @mink:chromedriver
Scenario: Filtering orders by multiple products
When I browse orders
And I filter by products "Galaxy T-Shirt" and "Space Dress"
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature
index 23ea147262..9f1d7e87b7 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature
@@ -23,7 +23,7 @@ Feature: Filtering orders by a shipping method
And the customer chose "DHL" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by DHL shipping method
When I browse orders
And I choose "DHL" as a shipping method filter
@@ -32,7 +32,7 @@ Feature: Filtering orders by a shipping method
And I should see an order with "#000001338" number
And I should not see an order with "#000001337" number
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by an another shipping method
When I browse orders
And I choose "Free" as a shipping method filter
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature
index 4fa36f9b1f..aba465fc3b 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature
@@ -18,14 +18,14 @@ Feature: Filtering orders by total in different currencies
And I am logged in as an administrator
And I am browsing orders
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by currency alone
When I choose "British Pound" as the filter currency
And I filter
Then I should see 3 orders in the list
But I should not see any orders with currency "USD"
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders with total greater than specified amount
When I choose "US Dollar" as the filter currency
And I specify filter total being greater than 100
@@ -36,7 +36,7 @@ Feature: Filtering orders by total in different currencies
But I should not see an order with "#00000001" number
And I should not see any orders with currency "GBP"
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders with total less than specified amount
When I choose "US Dollar" as the filter currency
And I specify filter total being less than 200
@@ -47,7 +47,7 @@ Feature: Filtering orders by total in different currencies
But I should not see an order with "#00000002" number
And I should not see any orders with currency "GBP"
- @ui @api
+ @todo @ui @api
Scenario: Filtering order with total from a specified range
When I choose "British Pound" as the filter currency
And I specify filter total being greater than 150.50
@@ -59,7 +59,7 @@ Feature: Filtering orders by total in different currencies
And I should not see an order with "#00000006" number
And I should not see any orders with currency "USD"
- @ui @api
+ @todo @ui @api
Scenario: Filtering orders by total in given range but with no currency provided
When I specify filter total being greater than 150
And I specify filter total being less than 200
diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature
index 007a7cdb3f..644091e2be 100644
--- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature
+++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature
@@ -26,7 +26,7 @@ Feature: Filtering orders by variants
And the customer chose "Free" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api @javascript
+ @todo @ui @api @javascript
Scenario: Filtering orders by variant
When I browse orders
And I filter by variant "Sundress"
@@ -34,7 +34,7 @@ Feature: Filtering orders by variants
And I should see an order with "#0000002" number
And I should see an order with "#0000003" number
- @ui @api @mink:chromedriver
+ @todo @ui @api @mink:chromedriver
Scenario: Filtering orders by multiple variants of the same product
When I browse orders
And I filter by variants "Nebula Top" and "Neutron Sleeveless"
@@ -42,7 +42,7 @@ Feature: Filtering orders by variants
And I should see an order with "#0000001" number
And I should see an order with "#0000002" number
- @ui @api @javascript
+ @todo @ui @api @javascript
Scenario: Filtering orders by multiple variants of different products
When I browse orders
And I filter by variants "Neutron Sleeveless" and "Sundress"
diff --git a/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature b/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature
index defce54801..25ca0e5499 100644
--- a/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature
+++ b/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature
@@ -11,7 +11,7 @@ Feature: Being redirected to previous filtered page
And this payment method has been disabled
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being redirected to previous filtered page after cancelling creating a new payment method
When I browse payment methods
And I choose enabled filter
diff --git a/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature b/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature
index 37288549b4..af19f7671e 100644
--- a/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature
+++ b/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature
@@ -7,10 +7,10 @@ Feature: Browsing payment methods
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing defined payment methods
Given the store has a payment method "Offline" with a code "OFF"
- And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and Paypal Express Checkout gateway
+ And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway
When I browse payment methods
Then I should see 2 payment methods in the list
And the payment method "PayPal Express Checkout" should be in the registry
diff --git a/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature b/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature
index 1dd7d0c9de..182ce5ccf9 100644
--- a/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature
+++ b/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature
@@ -7,10 +7,10 @@ Feature: Deleting multiple payment methods
Background:
Given the store has a payment method "Offline" with a code "Offline"
And the store has also a payment method "Bank transfer" with a code "transfer"
- And the store has also a payment method "PayPal Express Checkout" with a code "paypal" and Paypal Express Checkout gateway
+ And the store has also a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple payment methods at once
When I browse payment methods
And I check the "Offline" payment method
diff --git a/features/admin/payment/managing_payment_methods/deleting_payment_method.feature b/features/admin/payment/managing_payment_methods/deleting_payment_method.feature
index 3aafd8fe79..f5daea0d3a 100644
--- a/features/admin/payment/managing_payment_methods/deleting_payment_method.feature
+++ b/features/admin/payment/managing_payment_methods/deleting_payment_method.feature
@@ -8,7 +8,7 @@ Feature: Deleting payment methods
Given the store has a payment method "Offline" with a code "Offline"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted payment method should disappear from the registry
When I delete the "Offline" payment method
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method.feature b/features/admin/payment/managing_payment_methods/editing_payment_method.feature
index d3ca12fa2d..55cd21b3b6 100644
--- a/features/admin/payment/managing_payment_methods/editing_payment_method.feature
+++ b/features/admin/payment/managing_payment_methods/editing_payment_method.feature
@@ -15,7 +15,7 @@ Feature: Editing payment methods
And I rename it to "Cash on delivery" in "English (United States)"
And I save my changes
Then I should be notified that it has been successfully edited
- And this payment method name should be "Cash on delivery"
+ And this payment method "Name" should be "Cash on delivery"
@ui @api
Scenario: Disabling payment method
diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature b/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature
new file mode 100644
index 0000000000..033f4db2fe
--- /dev/null
+++ b/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature
@@ -0,0 +1,54 @@
+@managing_payment_methods
+Feature: Editing payment method configured with a PayPal Express Checkout gateway
+ In order to change configuration of a payment method
+ As an Administrator
+ I want to be able to edit payment method with a PayPal Express Checkout gateway
+
+ Background:
+ Given the store operates on a single channel in "United States"
+ And the store has a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway
+ And I am logged in as an administrator
+
+ @ui @no-api
+ Scenario: Changing gateway username
+ When I want to modify the "PayPal Express Checkout" payment method
+ And I update its "Username" with "new_username"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And its gateway configuration "Username" should be "new_username"
+
+ @ui @no-api
+ Scenario: Changing gateway password
+ When I want to modify the "PayPal Express Checkout" payment method
+ And I update its "Password" with "new_password"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And its gateway configuration "Password" should be "new_password"
+
+ @ui @no-api
+ Scenario: Changing gateway signature
+ When I want to modify the "PayPal Express Checkout" payment method
+ And I update its "Signature" with "new_signature"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And its gateway configuration "Signature" should be "new_signature"
+
+ @ui @no-api
+ Scenario: Changing gateway sandbox mode
+ When I want to modify the "PayPal Express Checkout" payment method
+ And I enable sandbox mode
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And this payment method should be in sandbox mode
+
+ @api @ui
+ Scenario: Changing whole gateway configuration
+ When I want to modify the "PayPal Express Checkout" payment method
+ And I set its "Username" as "new_username", "Password" as "new_password" and "Signature" as "new_signature"
+ And I enable sandbox mode
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And its gateway configuration "Username" should be "new_username"
+ And its gateway configuration "Password" should be "new_password"
+ And its gateway configuration "Signature" should be "new_signature"
+ And this payment method should be in sandbox mode
diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature b/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature
new file mode 100644
index 0000000000..331eccb42f
--- /dev/null
+++ b/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature
@@ -0,0 +1,35 @@
+@managing_payment_methods
+Feature: Editing payment method configured with a Stripe Checkout gateway
+ In order to change which payment methods are available in my store
+ As an Administrator
+ I want to be able to edit payment method
+
+ Background:
+ Given the store operates on a single channel in "United States"
+ And the store has a payment method "Stripe Checkout" with a code "stripe" and "Stripe Checkout" gateway
+ And I am logged in as an administrator
+
+ @ui @no-api
+ Scenario: Changing Stripe Checkout gateway publishable key
+ When I want to modify the "Stripe Checkout" payment method
+ And I update its "Publishable key" with "some_publishable_key"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And this payment method "Publishable key" should be "some_publishable_key"
+
+ @ui @no-api
+ Scenario: Changing Stripe Checkout gateway secret key
+ When I want to modify the "Stripe Checkout" payment method
+ And I update its "Secret key" with "some_secret_key"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And this payment method "Secret key" should be "some_secret_key"
+
+ @api @ui
+ Scenario: Changing whole gateway configuration
+ When I want to modify the "Stripe Checkout" payment method
+ And I set its "Publishable key" as "new_publishable_key" and "Secret key" as "new_secret_key"
+ And I save my changes
+ Then I should be notified that it has been successfully edited
+ And its gateway configuration "Publishable key" should be "new_publishable_key"
+ And its gateway configuration "Secret key" should be "new_secret_key"
diff --git a/features/admin/payment/managing_payment_methods/payment_method_validation.feature b/features/admin/payment/managing_payment_methods/payment_method_validation.feature
index 8495bd5fa1..4f818904c5 100644
--- a/features/admin/payment/managing_payment_methods/payment_method_validation.feature
+++ b/features/admin/payment/managing_payment_methods/payment_method_validation.feature
@@ -78,9 +78,9 @@ Feature: Payment method validation
When I want to create a new payment method with "Stripe Checkout" gateway factory
And I name it "Stripe Checkout" in "English (United States)"
And I specify its code as "SC"
- And I configure it with only "publishable key"
+ And I configure it with only "Publishable key"
And I add it
- Then I should be notified that I have to specify stripe "secret key"
+ Then I should be notified that I have to specify stripe "Secret key"
And the payment method with code "PEC" should not be added
@ui @api
@@ -88,9 +88,9 @@ Feature: Payment method validation
When I want to create a new payment method with "Stripe Checkout" gateway factory
And I name it "Stripe Checkout" in "English (United States)"
And I specify its code as "SC"
- And I configure it with only "secret key"
+ And I configure it with only "Secret key"
And I add it
- Then I should be notified that I have to specify stripe "publishable key"
+ Then I should be notified that I have to specify stripe "Publishable key"
And the payment method with code "PEC" should not be added
@no-ui @api
diff --git a/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature b/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature
index f847f46a28..8752424ad1 100644
--- a/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature
+++ b/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature
@@ -14,7 +14,7 @@ Feature: Prevent deletion of used payment method
And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Being unable to delete a payment method which is in use
When I try to delete the "Cash on Delivery" payment method
Then I should be notified that it is in use
diff --git a/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature b/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature
index b30c79cad3..2b00133ab9 100644
--- a/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature
+++ b/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature
@@ -7,7 +7,7 @@ Feature: Sorting listed payment methods
Background:
Given the store operates on a single channel in "United States"
And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales
- And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and Paypal Express Checkout gateway
+ And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway
And this payment method is named "Ekspresowy Paypal" in the "Polish (Poland)" locale
And the store has a payment method "Offline" with a code "Offline"
And this payment method is named "Płatność Offline" in the "Polish (Poland)" locale
@@ -15,14 +15,14 @@ Feature: Sorting listed payment methods
And this payment method is named "Płatność Przy Odbiorze" in the "Polish (Poland)" locale
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Payment methods can be sorted by their codes
Given I am browsing payment methods
When I start sorting payment methods by code
Then I should see 3 payment methods in the list
And the first payment method on the list should have code "cash_on_delivery"
- @ui @api
+ @todo @ui @api
Scenario: Changing the order of sorting payment methods by their codes
Given I am browsing payment methods
And the payment methods are already sorted by code
@@ -30,14 +30,14 @@ Feature: Sorting listed payment methods
Then I should see 3 payment methods in the list
And the first payment method on the list should have code "PAYPAL"
- @ui @api
+ @todo @ui @api
Scenario: Payment methods can be sorted by their names
Given I am browsing payment methods
When I start sorting payment methods by name
Then I should see 3 payment methods in the list
And the first payment method on the list should have name "Cash on Delivery"
- @ui @api
+ @todo @ui @api
Scenario: Changing the order of sorting payment methods by their names
Given I am browsing payment methods
And the payment methods are already sorted by name
@@ -45,7 +45,7 @@ Feature: Sorting listed payment methods
Then I should see 3 payment methods in the list
And the first payment method on the list should have name "PayPal Express Checkout"
- @ui @api
+ @todo @ui @api
Scenario: Payment methods are always sorted in the default locale
Given I change my locale to "Polish (Poland)"
And I am browsing payment methods
diff --git a/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature b/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature
index f4778dfe95..b95f120aef 100644
--- a/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature
+++ b/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature
@@ -11,20 +11,20 @@ Feature: Sorting listed payment methods by position
And the store allows paying with "Offline" at position 1
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Payment methods are sorted by position in ascending order by default
When I browse payment methods
Then I should see 3 payment methods in the list
And the first payment method on the list should have name "Paypal Express Checkout"
And the last payment method on the list should have name "Cash on Delivery"
- @ui @api
+ @todo @ui @api
Scenario: Payment method added at no position is added as the last one
Given the store allows paying with "Credit Card"
When I browse payment methods
Then the last payment method on the list should have name "Credit Card"
- @ui @api
+ @todo @ui @api
Scenario: Payment method added at position 0 is added as the first one
Given the store also allows paying with "Credit Card" at position 0
When I browse payment methods
diff --git a/features/admin/payment/managing_payments/browsing_payments.feature b/features/admin/payment/managing_payments/browsing_payments.feature
index b809cf1ef8..04588a9a1c 100644
--- a/features/admin/payment/managing_payments/browsing_payments.feature
+++ b/features/admin/payment/managing_payments/browsing_payments.feature
@@ -1,6 +1,6 @@
@managing_payments
Feature: Browsing payments
- In order to manage all payments regardlessly of orders
+ In order to manage all payments regardless of orders
As an Administrator
I want to browse all payments in the system
diff --git a/features/admin/payment/managing_payments/sorting_payments.feature b/features/admin/payment/managing_payments/sorting_payments.feature
new file mode 100644
index 0000000000..8fc448276f
--- /dev/null
+++ b/features/admin/payment/managing_payments/sorting_payments.feature
@@ -0,0 +1,28 @@
+@managing_payments
+Feature: Sorting payments
+ In order to manage all payments regardless of orders
+ As an Administrator
+ I want to sort payments by date
+
+ Background:
+ Given the store operates on a single channel in "United States"
+ And the store ships everywhere for Free
+ And the store has a product "Apple"
+ And the store allows paying with "Cash on Delivery"
+ And there is an "#00000001" order with "Apple" product
+ And there is an "#00000002" order with "Apple" product ordered later
+ And I am logged in as an administrator
+
+ @ui @api-todo
+ Scenario: Sorting payments by date in ascending order
+ When I browse payments
+ And I sort payments by date in ascending order
+ Then I should see payment for the "#00000001" order as 1st in the list
+ And I should see payment for the "#00000002" order as 2nd in the list
+
+ @ui @api-todo
+ Scenario: Sorting payments by date in descending order again
+ When I browse payments
+ And I sort payments by date in descending order
+ Then I should see payment for the "#00000002" order as 1st in the list
+ And I should see payment for the "#00000001" order as 2nd in the list
diff --git a/features/admin/placing_order_as_impersonated_customers.feature b/features/admin/placing_order_as_impersonated_customers.feature
index de0a14520e..51f0b91e99 100644
--- a/features/admin/placing_order_as_impersonated_customers.feature
+++ b/features/admin/placing_order_as_impersonated_customers.feature
@@ -13,7 +13,7 @@ Feature: Placing an order as impersonated shop users
And there is a customer "Tanith Low" identified by an email "tanith.low@london.uk" and a password "tanithlow"
And I am logged in as an administrator
- @ui
+ @todo @ui
Scenario: Placing an order as an impersonated shop user
When I view details of the customer "tanith.low@london.uk"
And I impersonate them
@@ -24,7 +24,7 @@ Feature: Placing an order as impersonated shop users
And I browse orders of a customer "tanith.low@london.uk"
Then I should see a single order in the list
- @ui
+ @todo @ui
Scenario: Placing an order as an impersonated shop user when the shop user was already logged
When I sign in with email "john.doe@london.uk" and password "johndoe"
And I view details of the customer "tanith.low@london.uk"
diff --git a/features/admin/product/managing_product_association_types/browsing_product_association_types.feature b/features/admin/product/managing_product_association_types/browsing_product_association_types.feature
index 181f1288e5..361a65f91f 100644
--- a/features/admin/product/managing_product_association_types/browsing_product_association_types.feature
+++ b/features/admin/product/managing_product_association_types/browsing_product_association_types.feature
@@ -9,7 +9,7 @@ Feature: Browsing product association types
And the store has also a product association type "Up sell"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing product association types in the store
When I want to browse product association types
Then I should see 2 product association types in the list
diff --git a/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature b/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature
index 52e7d75c54..1352c7caef 100644
--- a/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature
+++ b/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple product association types
And the store has also a product association type "Accessories"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple product association types at once
When I browse product association types
And I check the "Cross sell" product association type
diff --git a/features/admin/product/managing_product_association_types/filtering_product_association_types.feature b/features/admin/product/managing_product_association_types/filtering_product_association_types.feature
index 0c4b3a727b..188047a896 100644
--- a/features/admin/product/managing_product_association_types/filtering_product_association_types.feature
+++ b/features/admin/product/managing_product_association_types/filtering_product_association_types.feature
@@ -9,14 +9,14 @@ Feature: Filtering product association types
And the store has also a product association type "Up sell" with a code "up_sell"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering product association types by name
When I want to browse product association types
And I filter product association types with name containing "Up"
Then I should see only one product association type in the list
And I should see the product association type "Up sell" in the list
- @ui @api
+ @todo @ui @api
Scenario: Filtering product association types by code
When I want to browse product association types
And I filter product association types with code containing "cross"
diff --git a/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature
index effe7330a6..8ae0b23e61 100644
--- a/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new checkbox product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new checkbox product attribute
When I want to create a new checkbox product attribute
And I specify its code as "t_shirt_with_cotton"
@@ -17,7 +17,7 @@ Feature: Adding a new checkbox product attribute
Then I should be notified that it has been successfully created
And the checkbox attribute "T-Shirt with cotton" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a checkbox product attribute
When I want to create a new checkbox product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature
index 570cfaa36a..76ae2eed90 100644
--- a/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new float product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new float product attribute
When I want to create a new float product attribute
And I specify its code as "display_size"
@@ -17,7 +17,7 @@ Feature: Adding a new float product attribute
Then I should be notified that it has been successfully created
And the float attribute "Display Size" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a float product attribute
When I want to create a new float product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature
index 8a51d121d1..8ce0080d57 100644
--- a/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new integer product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new integer product attribute
When I want to create a new integer product attribute
And I specify its code as "book_pages"
@@ -17,7 +17,7 @@ Feature: Adding a new integer product attribute
Then I should be notified that it has been successfully created
And the integer attribute "Book pages" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a integer product attribute
When I want to create a new integer product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature b/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature
index 897e8fe7eb..e77362d4e4 100644
--- a/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new non-translatable product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new non-translatable product attribute
When I want to create a new integer product attribute
And I specify its code as "damage"
diff --git a/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature
index 8b4a7b8766..9825959ed1 100644
--- a/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new percent product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new percent product attribute
When I want to create a new percent product attribute
And I specify its code as "t_shirt_cotton_content"
@@ -17,7 +17,7 @@ Feature: Adding a new percent product attribute
Then I should be notified that it has been successfully created
And the percent attribute "T-Shirt cotton content" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a percent product attribute
When I want to create a new percent product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature
index d50fb2471a..4d2c6ad413 100644
--- a/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new select product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding a new select product attribute
When I want to create a new select product attribute
And I specify its code as "mug_material"
@@ -18,7 +18,7 @@ Feature: Adding a new select product attribute
Then I should be notified that it has been successfully created
And the select attribute "Mug material" should appear in the store
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding multiple select product attribute
When I want to create a new select product attribute
And I specify its code as "mug_material"
@@ -30,7 +30,7 @@ Feature: Adding a new select product attribute
Then I should be notified that it has been successfully created
And the select attribute "Mug material" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a select product attribute
When I want to create a new select product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature
index 41852229db..8ea4cdf240 100644
--- a/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new text product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new text product attribute
When I want to create a new text product attribute
And I specify its code as "t_shirt_brand"
@@ -17,7 +17,7 @@ Feature: Adding a new text product attribute
Then I should be notified that it has been successfully created
And the text attribute "T-Shirt brand" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding text a product attribute
When I want to create a new text product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature
index b8934594bf..46f7439113 100644
--- a/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature
@@ -8,7 +8,7 @@ Feature: Adding a new textarea product attribute
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new textarea product attribute
When I want to create a new textarea product attribute
And I specify its code as "t_shirt_details"
@@ -17,7 +17,7 @@ Feature: Adding a new textarea product attribute
Then I should be notified that it has been successfully created
And the textarea attribute "T-Shirt details" should appear in the store
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled type field while adding a textarea product attribute
When I want to create a new textarea product attribute
Then the type field should be disabled
diff --git a/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature b/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature
index 0d30a90736..2bd306a2ac 100644
--- a/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature
+++ b/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature
@@ -10,7 +10,7 @@ Feature: Browsing product attributes
And the store has a integer product attribute "Book pages" with code "book_pages"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing all product attributes in store
When I want to see all product attributes in store
Then I should see 3 product attributes in the list
diff --git a/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature b/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature
index 43137fc4a3..e1d86e950f 100644
--- a/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature
+++ b/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple product attributes
And the store has a integer product attribute "Pages"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple product attributes at once
When I browse product attributes
And I check the "Publisher" product attribute
diff --git a/features/admin/product/managing_product_attributes/deleting_product_attribute.feature b/features/admin/product/managing_product_attributes/deleting_product_attribute.feature
index a099670a31..df10f240c3 100644
--- a/features/admin/product/managing_product_attributes/deleting_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/deleting_product_attribute.feature
@@ -8,13 +8,13 @@ Feature: Deleting a product attribute
Given I am logged in as an administrator
And the store has a product "44 Magnum"
- @ui @api
+ @todo @ui @api
Scenario: Trying to delete an attribute from the registry when a product uses it
Given this product has a text attribute "Gun caliber" with value "11 mm"
When I delete this product attribute
Then I should be notified that it is in use
- @ui @api
+ @todo @ui @api
Scenario: Deleting a text product attribute when it's not used
Given the store has a text product attribute "Gun caliber"
When I delete this product attribute
diff --git a/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature b/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature
index 80c86be83a..b7ab31d5cc 100644
--- a/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature
@@ -9,7 +9,7 @@ Feature: Editing a select product attribute
And the store has a select product attribute "T-Shirt material" with value "Banana skin"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Editing a select product attribute name
When I want to edit this product attribute
And I change its name to "T-Shirt material" in "English (United States)"
@@ -17,7 +17,7 @@ Feature: Editing a select product attribute
Then I should be notified that it has been successfully edited
And the select attribute "T-Shirt material" should appear in the store
- @ui @api
+ @todo @ui @api
Scenario: Editing a select product attribute value
When I want to edit this product attribute
And I change its value "Banana skin" to "Orange skin"
@@ -25,7 +25,7 @@ Feature: Editing a select product attribute
Then I should be notified that it has been successfully edited
And this product attribute should have value "Orange skin"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding a new value to an existing select product attribute
When I want to edit this product attribute
And I add value "Orange skin" in "English (United States)"
@@ -33,7 +33,7 @@ Feature: Editing a select product attribute
Then I should be notified that it has been successfully edited
And this product attribute should have value "Orange skin"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Deleting a value from an existing select product attribute
When I want to edit this product attribute
And I delete value "Banana skin"
@@ -41,12 +41,12 @@ Feature: Editing a select product attribute
Then I should be notified that it has been successfully edited
And this product attribute should not have value "Banana skin"
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change code of an existing product attribute
When I want to edit this product attribute
Then I should not be able to edit its code
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change type of an existing product attribute
When I want to edit this product attribute
Then I should not be able to edit its type
diff --git a/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature b/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature
index 94403887b7..d8318f89c9 100644
--- a/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature
+++ b/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature
@@ -9,7 +9,7 @@ Feature: Editing a text product attribute
And the store has a text product attribute "T-Shirt cotton brand" with code "t_shirt_brand"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Editing product attribute name
When I want to edit this product attribute
And I change its name to "T-Shirt material" in "English (United States)"
@@ -17,12 +17,12 @@ Feature: Editing a text product attribute
Then I should be notified that it has been successfully edited
And the text attribute "T-Shirt material" should appear in the store
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change code of an existing product attribute
When I want to edit this product attribute
Then I should not be able to edit its code
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change type of an existing product attribute
When I want to edit this product attribute
Then I should not be able to edit its type
diff --git a/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature b/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature
index dab34888e7..968603dace 100644
--- a/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature
+++ b/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature
@@ -8,7 +8,7 @@ Feature: Product attribute unique code validation
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new product attribute with taken code
Given the store has a text product attribute "T-Shirt cotton material" with code "t_shirt_material"
When I want to create a new text product attribute
diff --git a/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature b/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature
index 9362431da5..08e6eb330a 100644
--- a/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature
+++ b/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature
@@ -8,7 +8,7 @@ Feature: Seeing correct select attribute values in different locale than default
Given the store is available in "French (France)"
And I am logged in as an administrator
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Seeing correct attribute values in different locale than default one
When I want to create a new select product attribute
And I specify its code as "mug_material"
diff --git a/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature b/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature
index eed542b5eb..eedc1f6d90 100644
--- a/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature
+++ b/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature
@@ -8,7 +8,7 @@ Feature: Select product attribute validation
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Trying to add a new select product attribute with wrong max entries value
When I want to create a new select product attribute
And I name it "Mug material" in "English (United States)"
@@ -22,7 +22,7 @@ Feature: Select product attribute validation
Then I should be notified that max entries value must be greater or equal to the min entries value
And the attribute with code "mug_material" should not appear in the store
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Trying to add a new select product attribute with wrong min entries value
When I want to create a new select product attribute
And I name it "Mug material" in "English (United States)"
@@ -36,7 +36,7 @@ Feature: Select product attribute validation
Then I should be notified that min entries value must be lower or equal to the number of added choices
And the attribute with code "mug_material" should not appear in the store
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Trying to add a new select product attribute with specified entries values but without multiple option
When I want to create a new select product attribute
And I name it "Mug material" in "English (United States)"
diff --git a/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature b/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature
index e4a77d1bb6..e3a5f55692 100644
--- a/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature
+++ b/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature
@@ -10,21 +10,21 @@ Feature: Sorting listed product attributes by position
And the store has a integer product attribute "Book pages" at position 0
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Product attributes are sorted by position in ascending order by default
When I want to see all product attributes in store
Then I should see 3 product attributes in the list
And the first product attribute on the list should have name "Book pages"
And the last product attribute on the list should have name "T-Shirt with cotton"
- @ui @api
+ @todo @ui @api
Scenario: Product attribute added at no position gets put at the bottom of the list
Given the store has also a text product attribute "Drive type"
When I want to see all product attributes in store
Then I should see 4 product attributes in the list
And the last product attribute on the list should have name "Drive type"
- @ui @api
+ @todo @ui @api
Scenario: Product attribute added at position 0 is added as the first one
Given the store has also a text product attribute "Drive type" at position 0
When I want to see all product attributes in store
diff --git a/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature b/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature
index 6f51b660c1..30ef5fef0c 100644
--- a/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature
+++ b/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature
@@ -16,7 +16,7 @@ Feature: Text product attribute validation
And I save my changes
Then I should be notified that the locale is not available
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new text product attribute without name
When I want to create a new text product attribute
And I specify its code as "t_shirt_with_cotton"
@@ -25,7 +25,7 @@ Feature: Text product attribute validation
Then I should be notified that name is required
And the attribute with code "t_shirt_with_cotton" should not appear in the store
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new text product attribute without code
When I want to create a new text product attribute
And I name it "T-Shirt brand" in "English (United States)"
@@ -34,7 +34,7 @@ Feature: Text product attribute validation
Then I should be notified that code is required
And the attribute with name "T-Shirt brand" should not appear in the store
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove name for existing text product attribute
Given the store has a text product attribute "T-Shirt cotton brand"
When I want to edit this product attribute
@@ -43,7 +43,7 @@ Feature: Text product attribute validation
Then I should be notified that name is required
And the text attribute "T-Shirt cotton brand" should still be in the store
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new text product attribute with wrong configuration
When I want to create a new text product attribute
And I name it "T-Shirt brand" in "English (United States)"
diff --git a/features/admin/product/managing_product_options/adding_product_option.feature b/features/admin/product/managing_product_options/adding_product_option.feature
index 9d120344d2..2872b809be 100644
--- a/features/admin/product/managing_product_options/adding_product_option.feature
+++ b/features/admin/product/managing_product_options/adding_product_option.feature
@@ -8,7 +8,7 @@ Feature: Adding a new product option
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Adding a new product option with two required option values
When I want to create a new product option
And I name it "T-Shirt size" in "English (United States)"
@@ -21,7 +21,7 @@ Feature: Adding a new product option
And product option "T-Shirt size" should have the "S" option value
And product option "T-Shirt size" should have the "M" option value
- @ui @api
+ @todo @ui @api
Scenario: Adding a new product option without any option values
When I want to create a new product option
And I name it "T-Shirt size" in "English (United States)"
@@ -31,7 +31,7 @@ Feature: Adding a new product option
Then I should be notified that it has been successfully created
And the product option "T-Shirt size" should appear in the registry
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding a new product option with one option value
When I want to create a new product option
And I name it "T-Shirt size" in "English (United States)"
diff --git a/features/admin/product/managing_product_options/browsing_product_options.feature b/features/admin/product/managing_product_options/browsing_product_options.feature
index b2f3638077..66c976df61 100644
--- a/features/admin/product/managing_product_options/browsing_product_options.feature
+++ b/features/admin/product/managing_product_options/browsing_product_options.feature
@@ -4,7 +4,7 @@ Feature: Browsing product options
As an Administrator
I want to be able to browse product options
- @ui @api
+ @todo @ui @api
Scenario: Browsing defined product options
Given I am logged in as an administrator
And the store has a product option "T-Shirt size" with a code "t_shirt_size"
diff --git a/features/admin/product/managing_product_options/deleting_multiple_product_options.feature b/features/admin/product/managing_product_options/deleting_multiple_product_options.feature
index 269f1480f9..b325132107 100644
--- a/features/admin/product/managing_product_options/deleting_multiple_product_options.feature
+++ b/features/admin/product/managing_product_options/deleting_multiple_product_options.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple product options
And the store has also a product option "T-Shirt brand"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple product options at once
When I browse product options
And I check the "T-Shirt size" product option
diff --git a/features/admin/product/managing_product_options/editing_product_option.feature b/features/admin/product/managing_product_options/editing_product_option.feature
index b80356f7f8..b0b0dae34c 100644
--- a/features/admin/product/managing_product_options/editing_product_option.feature
+++ b/features/admin/product/managing_product_options/editing_product_option.feature
@@ -9,7 +9,7 @@ Feature: Editing product options
And the store has a product option "T-Shirt size" with a code "t_shirt_size"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Renaming the product option
Given this product option has the "S" option value with code "t_shirt_size_s"
And this product option has also the "M" option value with code "t_shirt_size_m"
@@ -19,7 +19,7 @@ Feature: Editing product options
Then I should be notified that it has been successfully edited
And this product option name should be "T-Shirt color"
- @ui @api
+ @todo @ui @api
Scenario: Not being able to edit code of an existing product option
When I want to modify the "T-Shirt size" product option
Then I should not be able to edit its code
diff --git a/features/admin/product/managing_product_options/managing_values_of_product_option.feature b/features/admin/product/managing_product_options/managing_values_of_product_option.feature
index 330fbc7b2c..ba16c453ca 100644
--- a/features/admin/product/managing_product_options/managing_values_of_product_option.feature
+++ b/features/admin/product/managing_product_options/managing_values_of_product_option.feature
@@ -11,7 +11,7 @@ Feature: Managing option values of a product option
And this product option has also the "M" option value with code "OV2"
And I am logged in as an administrator
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Adding an option value to an existing product option
When I want to modify the "T-Shirt size" product option
And I add the "L" option value identified by "OV3"
@@ -19,7 +19,7 @@ Feature: Managing option values of a product option
Then I should be notified that it has been successfully edited
And this product option should have the "L" option value
- @ui @javascript @todo
+ @todo @ui @javascript @todo
Scenario: Removing an option value from an existing product option
Given this product option has also the "L" option value with code "OV3"
When I want to modify the "T-Shirt size" product option
@@ -28,7 +28,7 @@ Feature: Managing option values of a product option
Then I should be notified that it has been successfully edited
And this product option should not have the "L" option value
- @ui @javascript @todo
+ @todo @ui @javascript @todo
Scenario: Removing and adding a new option value to an existing product option
When I want to modify the "T-Shirt size" product option
And I delete the "M" option value of this product option
diff --git a/features/admin/product/managing_product_options/product_option_unique_code_validation.feature b/features/admin/product/managing_product_options/product_option_unique_code_validation.feature
index adca682c77..84f935fcfe 100644
--- a/features/admin/product/managing_product_options/product_option_unique_code_validation.feature
+++ b/features/admin/product/managing_product_options/product_option_unique_code_validation.feature
@@ -9,7 +9,7 @@ Feature: Product option unique code validation
And the store has a product option "T-Shirt size" with a code "t_shirt_size"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add product option with a taken code
When I want to create a new product option
And I name it "T-Shirt color" in "English (United States)"
diff --git a/features/admin/product/managing_product_options/product_option_validation.feature b/features/admin/product/managing_product_options/product_option_validation.feature
index 8ccf2ac9eb..464b091e61 100644
--- a/features/admin/product/managing_product_options/product_option_validation.feature
+++ b/features/admin/product/managing_product_options/product_option_validation.feature
@@ -9,7 +9,7 @@ Feature: Product option validation
And the store has a product option "T-Shirt color" with a code "t_shirt_color"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new product option without specifying its code
When I want to create a new product option
And I name it "T-Shirt size" in "English (United States)"
@@ -25,7 +25,7 @@ Feature: Product option validation
And I try to save my changes
Then I should be notified that the locale is not available
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new product option with a too long code
When I want to create a new product option
And I name it "T-Shirt size" in "English (United States)"
@@ -33,7 +33,7 @@ Feature: Product option validation
And I try to add it
Then I should be notified that code is too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new product option without specifying its name
When I want to create a new product option
And I specify its code as "t_shirt_size"
@@ -42,7 +42,7 @@ Feature: Product option validation
Then I should be notified that name is required
And the product option with code "t_shirt_size" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove name from an existing product option
When I want to modify the "T-Shirt color" product option
And I remove its name from "English (United States)" translation
diff --git a/features/admin/product/managing_product_options/sorting_product_options_by_position.feature b/features/admin/product/managing_product_options/sorting_product_options_by_position.feature
index bb1510261f..5ab25fcec4 100644
--- a/features/admin/product/managing_product_options/sorting_product_options_by_position.feature
+++ b/features/admin/product/managing_product_options/sorting_product_options_by_position.feature
@@ -10,20 +10,20 @@ Feature: Sorting listed product options by position
And the store has also a product option "Mug type" at position 1
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Product options are sorted by position in ascending order by default
When I browse product options
Then I should see 3 product options in the list
And the first product option in the list should have name "Mug size"
And the last product option in the list should have name "Mug color"
- @ui @api
+ @todo @ui @api
Scenario: Product option added at no position is added as the last one
Given the store has a product option "Mug shape"
When I browse product options
Then the last product option in the list should have name "Mug shape"
- @ui @api
+ @todo @ui @api
Scenario: Product option added at position 0 is added as the first one
Given the store has a product option "Mug shape" at position 0
When I browse product options
diff --git a/features/admin/product/managing_product_reviews/accepting_product_review.feature b/features/admin/product/managing_product_reviews/accepting_product_review.feature
index f6a3d9d3e5..245bb136c7 100644
--- a/features/admin/product/managing_product_reviews/accepting_product_review.feature
+++ b/features/admin/product/managing_product_reviews/accepting_product_review.feature
@@ -10,7 +10,7 @@ Feature: Accepting a product review
And this product has a new review titled "Awesome" and rated 4 added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Accepting a product review
When I want to browse product reviews
And I accept the "Awesome" product review
diff --git a/features/admin/product/managing_product_reviews/browsing_product_reviews.feature b/features/admin/product/managing_product_reviews/browsing_product_reviews.feature
index 5d41ea19be..7e4040830a 100644
--- a/features/admin/product/managing_product_reviews/browsing_product_reviews.feature
+++ b/features/admin/product/managing_product_reviews/browsing_product_reviews.feature
@@ -11,7 +11,7 @@ Feature: Browsing product reviews
And this product has also a review titled "Bad" and rated 1 with a comment "Really bad" added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing all product reviews in store
When I want to browse product reviews
Then I should see 2 reviews in the list
diff --git a/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature b/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature
index b6bd4d948f..2c8af09359 100644
--- a/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature
+++ b/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature
@@ -11,7 +11,7 @@ Feature: Deleting multiple product reviews
And this product has also a review titled "Cool" and rated 4 with a comment "Quite cool" added by customer "aquaman@dc.com"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple product reviews at once
When I browse product reviews
And I check the "Awesome" product review
diff --git a/features/admin/product/managing_product_reviews/deleting_product_review.feature b/features/admin/product/managing_product_reviews/deleting_product_review.feature
index 9b90ea16fd..144536ea4a 100644
--- a/features/admin/product/managing_product_reviews/deleting_product_review.feature
+++ b/features/admin/product/managing_product_reviews/deleting_product_review.feature
@@ -10,7 +10,7 @@ Feature: Deleting product reviews
And this product has a review titled "Awesome" and rated 5 with a comment "Nice product" added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleting a product review
When I delete the "Awesome" product review
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/product/managing_product_reviews/editing_product_review.feature b/features/admin/product/managing_product_reviews/editing_product_review.feature
index e39aa6ed4b..9ffadde663 100644
--- a/features/admin/product/managing_product_reviews/editing_product_review.feature
+++ b/features/admin/product/managing_product_reviews/editing_product_review.feature
@@ -10,7 +10,7 @@ Feature: Editing product reviews
And this product has a review titled "Awesome" and rated 4 with a comment "Nice product" added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Changing a title of a product review
Given this product has a review titled "Bewilderig" and rated 5 with a comment "Nice product" added by customer "ross@teammike.com"
When I want to modify the "Bewilderig" product review
@@ -19,7 +19,7 @@ Feature: Editing product reviews
Then I should be notified that it has been successfully edited
And this product review title should be "Bewildering"
- @ui @api
+ @todo @ui @api
Scenario: Changing a comment of a product review
Given this product has a review titled "Bewildering" and rated 5 with a comment "Nice prodct" added by customer "ross@teammike.com"
When I want to modify the "Bewildering" product review
@@ -28,7 +28,7 @@ Feature: Editing product reviews
Then I should be notified that it has been successfully edited
And this product review comment should be "Nice product"
- @ui @api @javascript
+ @todo @ui @api @javascript
Scenario: Changing a rating of a product review
When I want to modify the "Awesome" product review
And I choose 5 as its rating
@@ -36,12 +36,12 @@ Feature: Editing product reviews
Then I should be notified that it has been successfully edited
And this product review rating should be 5
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing a product's name while editing a product review
When I want to modify the "Awesome" product review
Then I should be editing review of product "Lamborghini Gallardo Model"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing a customer's name while editing a product review
When I want to modify the "Awesome" product review
Then I should see the customer's name "Mike Ross"
diff --git a/features/admin/product/managing_product_reviews/filtering_product_reviews.feature b/features/admin/product/managing_product_reviews/filtering_product_reviews.feature
index 047dc30cdb..11cc8aa834 100644
--- a/features/admin/product/managing_product_reviews/filtering_product_reviews.feature
+++ b/features/admin/product/managing_product_reviews/filtering_product_reviews.feature
@@ -11,7 +11,7 @@ Feature: Browsing product reviews
And this product has a new review titled "Bad" and rated 1 added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing accepted reviews
When I want to browse product reviews
And I choose "accepted" as a status filter
diff --git a/features/admin/product/managing_product_reviews/product_review_validation.feature b/features/admin/product/managing_product_reviews/product_review_validation.feature
index f94cc11dc7..0fdc24d7d5 100644
--- a/features/admin/product/managing_product_reviews/product_review_validation.feature
+++ b/features/admin/product/managing_product_reviews/product_review_validation.feature
@@ -10,7 +10,7 @@ Feature: Product review validation
And this product has a review titled "Awesome" and rated 4 with a comment "Nice product" added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove title from an existing product review
When I want to modify the "Awesome" product review
And I remove its title
@@ -18,7 +18,7 @@ Feature: Product review validation
Then I should be notified that title is required
And this product review should still be titled "Awesome"
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove comment from an existing product review
When I want to modify the "Awesome" product review
And I remove its comment
diff --git a/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature b/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature
index d3564507ad..006e44d2cd 100644
--- a/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature
+++ b/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature
@@ -11,7 +11,7 @@ Feature: Recalculating product average rating
And this product has a review titled "Not bad" and rated 3 with a comment "Not bad car" added by customer "specter@teamharvey.com"
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Product's average rating is correctly recalculated after review's rate change
When I want to modify the "Awesome" product review
And I choose 5 as its rating
@@ -19,7 +19,7 @@ Feature: Recalculating product average rating
Then I should be notified that it has been successfully edited
And average rating of product "Lamborghini Gallardo Model" should be 4
- @ui @api
+ @todo @ui @api
Scenario: Product's average rating is correctly recalculated after review's rate change
When I delete the "Awesome" product review
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/product/managing_product_reviews/rejecting_product_review.feature b/features/admin/product/managing_product_reviews/rejecting_product_review.feature
index 94e360df3e..afa424dbf8 100644
--- a/features/admin/product/managing_product_reviews/rejecting_product_review.feature
+++ b/features/admin/product/managing_product_reviews/rejecting_product_review.feature
@@ -10,7 +10,7 @@ Feature: Rejecting a product review
And this product has a new review titled "Crap" and rated 1 added by customer "ross@teammike.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Rejecting a product review
When I want to browse product reviews
And I reject the "Crap" product review
diff --git a/features/admin/product/managing_product_variants/adding_product_variant.feature b/features/admin/product/managing_product_variants/adding_product_variant.feature
index efaac6f00c..fbb9a30b8e 100644
--- a/features/admin/product/managing_product_variants/adding_product_variant.feature
+++ b/features/admin/product/managing_product_variants/adding_product_variant.feature
@@ -20,7 +20,7 @@ Feature: Adding a new product variant
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
@api @ui
Scenario: Adding a new product variant with name
@@ -34,9 +34,9 @@ Feature: Adding a new product variant
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Vodka Wyborowa Premium" in "English (United States)" locale
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Wódka Wyborowa Premium" in "Polish (Poland)" locale
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Vodka Wyborowa Premium" in "English (United States)" locale
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Wódka Wyborowa Premium" in "Polish (Poland)" locale
@api @ui
Scenario: Adding a new product variant with specific option's value
@@ -69,8 +69,8 @@ Feature: Adding a new product variant
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA_EXQUISITE" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_EXQUISITE" should be priced at "$100.00" for channel "United States"
- And the variant with code "VODKA_WYBOROWA_EXQUISITE" should have an original price of "$120.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_EXQUISITE" should be priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_EXQUISITE" should have an original price of "$120.00" for channel "United States"
@api @ui
Scenario: Adding a new product variant without shipping required
@@ -81,9 +81,9 @@ Feature: Adding a new product variant
And I set its "Taste" option to "Orange"
And I add it
Then I should be notified that it has been successfully created
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should not have shipping required
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should not have shipping required
And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States"
@api @ui
Scenario: Adding a new free product variant
@@ -94,7 +94,7 @@ Feature: Adding a new product variant
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$0.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$0.00" for channel "United States"
@api @ui
Scenario: Adding a new product variant with minimum price
@@ -106,5 +106,5 @@ Feature: Adding a new product variant
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA" should be priced at "$100.00" for channel "United States"
- And the variant with code "VODKA_WYBOROWA" should have minimum price "$50.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA" should be priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA" should have minimum price "$50.00" for channel "United States"
diff --git a/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature b/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature
index 051607d794..5bc168adc9 100644
--- a/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature
+++ b/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature
@@ -18,4 +18,4 @@ Feature: Adding a product variant with only original price
And I add it
Then I should be notified that it has been successfully created
And the "VODKA_WYBOROWA_DELUX" variant of the "Wyborowa Vodka" product should appear in the store
- And the variant with code "VODKA_WYBOROWA_DELUX" should be originally priced at "$100.00" for channel "United States"
+# And the variant with code "VODKA_WYBOROWA_DELUX" should be originally priced at "$100.00" for channel "United States"
diff --git a/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature b/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature
index 08dc47350a..da722438be 100644
--- a/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature
+++ b/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature
@@ -10,7 +10,7 @@ In order to check a product in shop in all channels it is available in
And the store has a product "Bugatti" available in "United States" channel
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing product show page in shop from the product variant edit page where product is available in more than one channel
Given this product is also available in the "Europe" channel
And this product has "Red" variant priced at "$220,000.00" in "Europe" channel
@@ -18,14 +18,14 @@ In order to check a product in shop in all channels it is available in
And I choose to show this product in the "Europe" channel
Then I should see this product in the "Europe" channel in the shop
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing product show page in shop from the product variant edit page where product is available in one channel
Given this product has "Red" variant priced at "$220,000.00" in "United States" channel
When I want to modify the "Bugatti" product variant
And I choose to show this product in this channel
Then I should see this product in the "United States" channel in the shop
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being unable to access product show page in shop when the product is disabled
Given this product has been disabled
When I want to modify the "Bugatti" product variant
diff --git a/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature b/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature
index 7add26f9ef..fb2bb1696f 100644
--- a/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature
+++ b/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple product variants
And this product has "Small PHP Mug", "Medium PHP Mug" and "Big PHP Mug" variants
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple product variants at once
When I browse variants of this product
And I check the "Small PHP Mug" product variant
diff --git a/features/admin/product/managing_product_variants/generating_product_variant_validation.feature b/features/admin/product/managing_product_variants/generating_product_variant_validation.feature
index 80272db012..17cbfd4dc9 100644
--- a/features/admin/product/managing_product_variants/generating_product_variant_validation.feature
+++ b/features/admin/product/managing_product_variants/generating_product_variant_validation.feature
@@ -58,3 +58,10 @@ Feature: Generating product variant generation
And I should be notified that code is required for the 2nd variant
And I should be notified that prices in all channels must be defined for the 2nd variant
And I should not see any variants in the list
+
+ @ui @no-api
+ Scenario: Trying to remove an existing product variant during generation
+ Given the product "Wyborowa Vodka" has "Wyborowa Vodka Orange" variant priced at "$40.00" configured with "Orange" option value
+ When I want to generate new variants for this product
+ Then I should not be able to remove 1st product variant
+ And I should be able to remove 2nd product variant
diff --git a/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature b/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature
index b3c9a680b4..b3954f3d3d 100644
--- a/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature
+++ b/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature
@@ -44,7 +44,7 @@ Feature: Sorting listed product variants from a product by position
Scenario: Setting product variant as the first one in the list
When I view all variants of the product "Opel Insignia"
And I set the position of "Opel Insignia Sedan" to 0
- And I save my new configuration
+ And I save my new elements order
And I view all variants of the product "Opel Insignia" again
Then the first variant in the list should have name "Opel Insignia Sedan"
@@ -52,6 +52,6 @@ Feature: Sorting listed product variants from a product by position
Scenario: Setting product variant as the last one in the list
When I view all variants of the product "Opel Insignia"
And I set the position of "Opel Insignia Sedan" to 7
- And I save my new configuration
+ And I save my new elements order
And I view all variants of the product "Opel Insignia" again
Then the last variant in the list should have name "Opel Insignia Sedan"
diff --git a/features/admin/product/managing_products/accessing_stores_product_page.feature b/features/admin/product/managing_products/accessing_stores_product_page.feature
index f6dcf8ce5a..7e26ace06d 100644
--- a/features/admin/product/managing_products/accessing_stores_product_page.feature
+++ b/features/admin/product/managing_products/accessing_stores_product_page.feature
@@ -10,7 +10,7 @@ Feature: Accessing a store's product page
And I am logged in as an administrator
And I am using "Polish (Poland)" locale for my panel
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing the product shop page from the admin panel when the product has a translation with a defined slug in the administrator's chosen language
Given the locale "Polish (Poland)" is enabled
And this product is named "Bulldog francuski T-Shirt" in the "Polish (Poland)" locale
@@ -18,7 +18,7 @@ Feature: Accessing a store's product page
Then the show product's page button should be enabled
And it should be leading to the product's page in the "Polish (Poland)" locale
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing the product shop page from the admin panel when the product has a translation with a defined slug in the default channel's language
Given the locale "French (France)" is enabled
And this product is named "Tee-shirt bouledogue français" in the "French (France)" locale
@@ -26,7 +26,7 @@ Feature: Accessing a store's product page
Then the show product's page button should be enabled
And it should be leading to the product's page in the "German (Germany)" locale
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing the product shop page from the admin panel with using first available locale with slug and enabled in the channel
Given the locale "French (France)" is enabled
And the store also operates in "French (France)" locale
@@ -36,7 +36,7 @@ Feature: Accessing a store's product page
Then the show product's page button should be enabled
And it should be leading to the product's page in the "French (France)" locale
- @ui @no-api
+ @todo @ui @no-api
Scenario: Not being able to access the product shop page from the admin panel when the product has no translations meeting the criteria
Given this product has no translations with a defined slug
When I want to edit this product
diff --git a/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature b/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature
index f3084b9a8e..88a6ab1962 100644
--- a/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature
+++ b/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature
@@ -10,19 +10,19 @@ Feature: Accessing the variants management from the product edit page
And this product has option "Model" with values "RS6" and "RS7"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being able to access the variants list page
When I modify the "Audi" product
And I go to the variants list
Then I should be on the list of this product's variants
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being able to access the variant creation page
When I modify the "Audi" product
And I go to the variant creation page
Then I should be on the variant creation page for this product
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being able to access the variant generation page
When I modify the "Audi" product
And I go to the variant generation page
diff --git a/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature b/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature
index 1a4cf716ae..ca59165399 100644
--- a/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature
+++ b/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature
@@ -10,7 +10,7 @@ Feature: Adding a new integer product attribute
And the store has a non-translatable text product attribute "ISBN"
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding two text attributes to a product
When I want to create a new configurable product
And I specify its code as "HARRY_POTTER_1"
diff --git a/features/admin/product/managing_products/adding_product.feature b/features/admin/product/managing_products/adding_product.feature
index 0c19302a3f..0564c8e6e1 100644
--- a/features/admin/product/managing_products/adding_product.feature
+++ b/features/admin/product/managing_products/adding_product.feature
@@ -9,53 +9,70 @@ Feature: Adding a new product
And the store has "Standard" shipping category
And I am logged in as an administrator
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Adding a new simple product with price
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
And I name it "Dice Brewing" in "English (United States)"
- And I set its slug to "dice-brewing" in "English (United States)"
And I set its price to "$10.00" for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the product "Dice Brewing" should appear in the store
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Adding a new simple product with discounted price
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
And I name it "Dice Brewing" in "English (United States)"
- And I set its slug to "dice-brewing" in "English (United States)"
And I set its price to "$10.00" for "United States" channel
And I set its original price to "$20.00" for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the product "Dice Brewing" should appear in the store
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Adding a new simple Free product
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
And I name it "Dice Brewing" in "English (United States)"
- And I set its slug to "dice-brewing" in "English (United States)"
And I set its price to "$0.00" for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the product "Dice Brewing" should appear in the store
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Adding a new simple product with specific shipping category
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
And I name it "Dice Brewing" in "English (United States)"
And I set its price to "$10.00" for "United States" channel
- And I set its slug to "dice-brewing" in "English (United States)"
And I set its shipping category as "Standard"
And I add it
Then I should be notified that it has been successfully created
And the product "Dice Brewing" should appear in the store
- @ui @javascript @api
+ @ui @mink:chromedriver @no-api
+ Scenario: Adding a new simple product without shipping required
+ When I want to create a new simple product
+ And I specify its code as "BOARD_DICE_BREWING"
+ And I name it "Dice Brewing" in "English (United States)"
+ And I set its price to "$10.00" for "United States" channel
+ And I do not want to have shipping required for this product
+ And I add it
+ Then I should be notified that it has been successfully created
+ And the product "Dice Brewing" should not have shipping required
+ And the product "Dice Brewing" should appear in the store
+
+ @ui @mink:chromedriver @api
+ Scenario: Adding a new configurable product without options
+ When I want to create a new configurable product
+ And I specify its code as "WHISKEY_GENTLEMEN"
+ And I name it "Gentleman Jack" in "English (United States)"
+ And I add it
+ Then I should be notified that it has been successfully created
+ And the product "Gentleman Jack" should appear in the store
+
+ @ui @mink:chromedriver @api
Scenario: Adding a new configurable product
Given the store has a product option "Bottle size" with a code "bottle_size"
And this product option has the "0.7" option value with code "bottle_size_medium"
@@ -64,30 +81,6 @@ Feature: Adding a new product
And I specify its code as "WHISKEY_GENTLEMEN"
And I name it "Gentleman Jack" in "English (United States)"
And I add the "Bottle size" option to it
- And I set its slug to "whiskey/gentleman-jack" in "English (United States)"
And I add it
Then I should be notified that it has been successfully created
And the product "Gentleman Jack" should appear in the store
-
- @ui @api
- Scenario: Adding a new configurable product without options
- When I want to create a new configurable product
- And I specify its code as "WHISKEY_GENTLEMEN"
- And I name it "Gentleman Jack" in "English (United States)"
- And I set its slug to "whiskey/gentleman-jack" in "English (United States)"
- And I add it
- Then I should be notified that it has been successfully created
- And the product "Gentleman Jack" should appear in the store
-
- @ui @no-api
- Scenario: Adding a new simple product without shipping required
- When I want to create a new simple product
- And I specify its code as "BOARD_DICE_BREWING"
- And I name it "Dice Brewing" in "English (United States)"
- And I set its slug to "dice-brewing" in "English (United States)"
- And I set its price to "$10.00" for "United States" channel
- And I do not want to have shipping required for this product
- And I add it
- Then I should be notified that it has been successfully created
- And the product "Dice Brewing" should not have shipping required
- And the product "Dice Brewing" should appear in the store
diff --git a/features/admin/product/managing_products/adding_product_with_associations.feature b/features/admin/product/managing_products/adding_product_with_associations.feature
index c80f2428bd..474573287b 100644
--- a/features/admin/product/managing_products/adding_product_with_associations.feature
+++ b/features/admin/product/managing_products/adding_product_with_associations.feature
@@ -48,5 +48,5 @@ Feature: Adding a new product with associations
And I associate as 123 the "LG headphones" and "LG earphones" products
And I add it
Then I should be notified that it has been successfully created
- And this product should have an association 123 with products "LG headphones" and "LG earphones"
+ And this product should have an association "123" with products "LG headphones" and "LG earphones"
And the product "LG G3" should appear in the store
diff --git a/features/admin/product/managing_products/adding_product_with_only_original_price.feature b/features/admin/product/managing_products/adding_product_with_only_original_price.feature
index 10c2c10568..67e6e31a22 100644
--- a/features/admin/product/managing_products/adding_product_with_only_original_price.feature
+++ b/features/admin/product/managing_products/adding_product_with_only_original_price.feature
@@ -8,7 +8,7 @@ Feature: Adding a product with only original price
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product without price
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
diff --git a/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature b/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature
index 6d9642daa8..11556d81cd 100644
--- a/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature
+++ b/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature
@@ -10,7 +10,7 @@ Feature: Adding product with prices for multiple channels
And the store operates on another channel named "Web-GB" in "GBP" currency
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Configure prices for each channel and currency while adding a new simple product
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -23,7 +23,7 @@ Feature: Adding product with prices for multiple channels
And product "Dice Brewing" should be priced at $10.00 for channel "Web-US"
And product "Dice Brewing" should be priced at £5.00 for channel "Web-GB"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Configure prices for each channel while adding a new simple product
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -33,7 +33,7 @@ Feature: Adding product with prices for multiple channels
And I add it
Then I should be notified that price must be defined for every channel
- @ui @no-api
+ @todo @ui @no-api
Scenario: Require prices only for chosen channels
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -45,7 +45,7 @@ Feature: Adding product with prices for multiple channels
Then I should be notified that it has been successfully created
And product "Dice Brewing" should be priced at $10.00 for channel "Web-US"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Require prices for all chosen channels
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -57,7 +57,7 @@ Feature: Adding product with prices for multiple channels
And I add it
Then I should be notified that price must be defined for every channel
- @ui @no-api
+ @todo @ui @no-api
Scenario: Do not specify price while adding a new simple product
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
diff --git a/features/admin/product/managing_products/browsing_products.feature b/features/admin/product/managing_products/browsing_products.feature
index eb715d8c75..b43bdec3d7 100644
--- a/features/admin/product/managing_products/browsing_products.feature
+++ b/features/admin/product/managing_products/browsing_products.feature
@@ -8,7 +8,7 @@ Feature: Browsing products
Given the store has "Dice Brewing" and "Eclipse" products
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing defined products
When I want to browse products
Then I should see 2 products in the list
diff --git a/features/admin/product/managing_products/browsing_products_by_taxon.feature b/features/admin/product/managing_products/browsing_products_by_taxon.feature
index 81c274af8a..9747079a4e 100644
--- a/features/admin/product/managing_products/browsing_products_by_taxon.feature
+++ b/features/admin/product/managing_products/browsing_products_by_taxon.feature
@@ -10,14 +10,14 @@ Feature: Browsing products
And this product belongs to "Pugs"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing all products
Given the store has a product "Doge mascot"
When I am browsing products
Then I should see a product with name "Young pug"
And I should see a product with name "Doge mascot"
- @ui @api
+ @todo @ui @api
Scenario: Browsing only products from specified category
Given I am browsing products
And the store has a product "Colorful mug"
diff --git a/features/admin/product/managing_products/deleting_multiple_products.feature b/features/admin/product/managing_products/deleting_multiple_products.feature
index 1b2bd5b4f1..200d27b771 100644
--- a/features/admin/product/managing_products/deleting_multiple_products.feature
+++ b/features/admin/product/managing_products/deleting_multiple_products.feature
@@ -8,7 +8,7 @@ Feature: Deleting multiple products
Given the store has "Audi RS5 model", "Audi RS6 model" and "Audi RS7 model" products
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple products at once
When I browse products
And I check the "Audi RS5 model" product
diff --git a/features/admin/product/managing_products/deleting_product.feature b/features/admin/product/managing_products/deleting_product.feature
index 454684c458..b42d37bb8a 100644
--- a/features/admin/product/managing_products/deleting_product.feature
+++ b/features/admin/product/managing_products/deleting_product.feature
@@ -11,7 +11,7 @@ Feature: Deleting a product
And this product has one review from customer "john@doe.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted product disappears from the product catalog
When I delete the "Toyota GT86 model" product
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/product/managing_products/deleting_product_with_reviews.feature b/features/admin/product/managing_products/deleting_product_with_reviews.feature
index 074502ca89..b9ca48eb1f 100644
--- a/features/admin/product/managing_products/deleting_product_with_reviews.feature
+++ b/features/admin/product/managing_products/deleting_product_with_reviews.feature
@@ -9,7 +9,7 @@ Feature: Deleting a product with its reviews
And this product has one review from customer "john@doe.com"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted product reviews disappear from the product catalog
When I delete the "Toyota GT86 model" product
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/product/managing_products/editing_product.feature b/features/admin/product/managing_products/editing_product.feature
index 53f1134270..66a506e473 100644
--- a/features/admin/product/managing_products/editing_product.feature
+++ b/features/admin/product/managing_products/editing_product.feature
@@ -9,12 +9,12 @@ Feature: Editing a product
And the store has a product "Dice Brewing"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change code of an existing product
When I want to modify the "Dice Brewing" product
Then I should not be able to edit its code
- @ui @no-api
+ @todo @ui @no-api
Scenario: Renaming a simple product
When I want to modify the "Dice Brewing" product
And I rename it to "7 Wonders" in "English (United States)"
@@ -22,7 +22,7 @@ Feature: Editing a product
Then I should be notified that it has been successfully edited
And this product name should be "7 Wonders"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Renaming a simple product does not change its variant name
Given this product only variant was renamed to "Dice Brewing: The Game"
When I want to modify this product
@@ -31,7 +31,7 @@ Feature: Editing a product
And I want to view all variants of this product
Then the first variant in the list should have name "Dice Brewing: The Game"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Changing a simple product price
When I want to modify the "Dice Brewing" product
And I change its price to $15.00 for "United States" channel
@@ -39,7 +39,7 @@ Feature: Editing a product
Then I should be notified that it has been successfully edited
And it should be priced at $15.00 for channel "United States"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Changing a simple product price
When I want to modify the "Dice Brewing" product
And I change its price to $7.50 for "United States" channel
@@ -49,7 +49,7 @@ Feature: Editing a product
And it should be priced at $7.50 for channel "United States"
And its original price should be "$15.00" for channel "United States"
- @ui @api
+ @todo @ui @api
Scenario: Renaming a configurable product
Given the store has a "Wyborowa Vodka" configurable product
When I want to modify this product
@@ -58,7 +58,7 @@ Feature: Editing a product
Then I should be notified that it has been successfully edited
And this product name should be "Sobieski Vodka"
- @ui @api
+ @todo @ui @api
Scenario: Renaming a configurable product with option
Given the store has a "Wyborowa Vodka" configurable product
And the store has a product option "Bottle size" with a code "bottle_size"
@@ -69,7 +69,7 @@ Feature: Editing a product
Then I should be notified that it has been successfully edited
And this product name should be "Sobieski Vodka"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Changing options of configurable product without any variant defined
Given the store has a "Marvel's T-Shirt" configurable product
And the store has a product option "T-Shirt size" with a code "t_shirt_size"
@@ -81,7 +81,7 @@ Feature: Editing a product
Then I should be notified that it has been successfully edited
And this product should have a "T-Shirt color" option
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change options of an existing product
Given the store has a "Marvel's T-Shirt" configurable product
And the store has a product option "T-Shirt size" with a code "t_shirt_size"
@@ -91,7 +91,7 @@ Feature: Editing a product
When I want to modify the "Marvel's T-Shirt" product
Then I should not be able to edit its options
- @ui @api
+ @todo @ui @api
Scenario: Enabling product in channel when all its variants already have specified price in this channel
Given the store operates on another channel named "Mobile"
And the store has a "7 Wonders" configurable product
diff --git a/features/admin/product/managing_products/editing_product_attributes.feature b/features/admin/product/managing_products/editing_product_attributes.feature
deleted file mode 100644
index 3d8ca4fc5c..0000000000
--- a/features/admin/product/managing_products/editing_product_attributes.feature
+++ /dev/null
@@ -1,28 +0,0 @@
-@managing_products
-Feature: Editing product's attributes
- In order to modify product details
- As an Administrator
- I want to be able to edit product's attributes
-
- Background:
- Given the store operates on a single channel in "United States"
- And the store has a product "44 Magnum"
- And the store has a text product attribute "Overall length"
- And this product has a text attribute "Gun caliber" with value "11 mm"
- And I am logged in as an administrator
-
- @ui @javascript @no-api
- Scenario: Seeing message about no new attributes selected
- When I want to modify the "44 Magnum" product
- And I try to add new attributes
- And I save my changes
- Then attribute "Gun caliber" of product "44 Magnum" should be "11 mm"
- And product "44 Magnum" should have 1 attribute
-
- @ui @javascript @no-api
- Scenario: Seeing message about no new attributes selected after all attributes deletion
- When I want to modify the "44 Magnum" product
- And I remove its "Gun caliber" attribute
- And I try to add new attributes
- And I save my changes
- Then product "44 Magnum" should not have any attributes
diff --git a/features/admin/product/managing_products/editing_product_slug.feature b/features/admin/product/managing_products/editing_product_slug.feature
index f34a603f8f..69045abe15 100644
--- a/features/admin/product/managing_products/editing_product_slug.feature
+++ b/features/admin/product/managing_products/editing_product_slug.feature
@@ -8,7 +8,7 @@ Feature: Editing product's slug
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Creating a product with an autogenerated slug
When I want to create a new configurable product
And I specify its code as "BOARD_MANSION_OF_MADNESS"
@@ -16,7 +16,7 @@ Feature: Editing product's slug
And I add it
Then the slug of the "Mansion of Madness" product should be "mansion-of-madness"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Creating a product with a custom slug
When I want to create a new configurable product
And I specify its code as "BOARD_MANSION_OF_MADNESS"
@@ -25,13 +25,13 @@ Feature: Editing product's slug
And I add it
Then the slug of the "Mansion of Madness" product should be "mom-board-game"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled slug field when editing a product
Given the store has a product "Mansion of Madness"
When I want to modify this product
Then the slug field should not be editable
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Prevent from editing a slug while changing a product name
Given the store has a product "Mansion of Madness"
When I want to modify this product
@@ -39,7 +39,7 @@ Feature: Editing product's slug
And I save my changes
Then the slug of the "Mansion of Madness: Second Edition" product should still be "mansion-of-madness"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Automatically changing a product's slug while editing a product's name
Given the store has a product "Mansion of Madness"
When I want to modify this product
@@ -48,7 +48,7 @@ Feature: Editing product's slug
And I save my changes
Then the slug of the "Small World" product should be "small-world"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Manually changing a product's slug while editing a product's name
Given the store has a product "Mansion of Madness"
When I want to modify this product
diff --git a/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature b/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature
index 40b0cc6b22..b05fbdd7b2 100644
--- a/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature
+++ b/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature
@@ -10,7 +10,7 @@ Feature: Editing product's slug in multiple locales
And the store is also available in "Polish (Poland)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Creating a product with custom slugs
When I want to create a new configurable product
And I specify its code as "PUG_PUGGINTON_PLUSHIE"
@@ -22,7 +22,7 @@ Feature: Editing product's slug in multiple locales
Then the slug of the "Pug Pugginton Plushie" product should be "sir-pugginton" in the "English (United States)" locale
And the slug of the "Pug Pugginton Plushie" product should be "pan-mopsinski" in the "Polish (Poland)" locale
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Creating a product with autogenerated slugs
When I want to create a new configurable product
And I specify its code as "PUG_PUGGINTON_PLUSHIE"
@@ -32,14 +32,14 @@ Feature: Editing product's slug in multiple locales
Then the slug of the "Pug Pugginton Plushie" product should be "pug-pugginton-plushie" in the "English (United States)" locale
And the slug of the "Pug Pugginton Plushie" product should be "pluszak-mops-mopsinski" in the "Polish (Poland)" locale
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled slug fields when editing a product
Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale
When I want to modify this product
Then the slug field in "English (United States)" should not be editable
And the slug field in "Polish (Poland)" also should not be editable
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Slugs don't get updated while changing product's names
Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale
When I want to modify this product
@@ -49,7 +49,7 @@ Feature: Editing product's slug in multiple locales
Then this product should still have slug "pug-pugginton-plushie" in "English (United States)" locale
And this product should still have slug "pluszak-mops-mopsinski" in "Polish (Poland)" locale
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Enabling automatic slugs update on product's names change
Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale
When I want to modify this product
@@ -61,7 +61,7 @@ Feature: Editing product's slug in multiple locales
Then this product should have slug "pug-pugston-the-third-plushie" in "English (United States)" locale
And this product should have slug "pluszak-mops-mopsak-trzeci" in "Polish (Poland)" locale
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Manually modifying slugs on product's names change
Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale
When I want to modify this product
diff --git a/features/admin/product/managing_products/filtering_products_by_channel.feature b/features/admin/product/managing_products/filtering_products_by_channel.feature
index 990001a747..542061ef84 100644
--- a/features/admin/product/managing_products/filtering_products_by_channel.feature
+++ b/features/admin/product/managing_products/filtering_products_by_channel.feature
@@ -12,7 +12,7 @@ Feature: Filtering products by a channel
And the store also has a product "HP Spectre" in channel "Web-US"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering products by a chosen channel
When I browse products
And I choose "Web-EU" as a channel filter
@@ -22,7 +22,7 @@ Feature: Filtering products by a channel
And I should see a product with name "MacBook Pro"
But I should not see any product with name "HP Spectre"
- @ui @api
+ @todo @ui @api
Scenario: Filtering products by a chosen channel
When I browse products
And I choose "Web-US" as a channel filter
diff --git a/features/admin/product/managing_products/adding_product_with_date_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_date_attribute.feature
similarity index 100%
rename from features/admin/product/managing_products/adding_product_with_date_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_date_attribute.feature
diff --git a/features/admin/product/managing_products/adding_product_with_datetime_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_datetime_attribute.feature
similarity index 100%
rename from features/admin/product/managing_products/adding_product_with_datetime_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_datetime_attribute.feature
diff --git a/features/admin/product/managing_products/adding_product_with_float_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature
similarity index 94%
rename from features/admin/product/managing_products/adding_product_with_float_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature
index 8d19c932b0..51372b4750 100644
--- a/features/admin/product/managing_products/adding_product_with_float_attribute.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature
@@ -9,11 +9,12 @@ Feature: Adding a new product with a float attribute
And the store has a non-translatable float product attribute "Display Size"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a float attribute to a product
When I want to create a new configurable product
And I specify its code as "display_size"
And I name it "Smartphone" in "English (United States)"
+ And I add the "Display Size" attribute to it
And I set its non-translatable "Display Size" attribute to 12.5
And I add it
Then I should be notified that it has been successfully created
diff --git a/features/admin/product/managing_products/adding_product_with_integer_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature
similarity index 91%
rename from features/admin/product/managing_products/adding_product_with_integer_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature
index 4226470be4..66dda909f6 100644
--- a/features/admin/product/managing_products/adding_product_with_integer_attribute.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature
@@ -15,7 +15,8 @@ Feature: Adding a new product with an integer attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
- And I set its "Production year" attribute to 1955 in "English (United States)"
+ And I add the "Production year" attribute to it
+ And I set the "Production year" attribute value to 1955 in "English (United States)"
And I add it
Then I should be notified that it has been successfully created
And the product "44 Magnum" should appear in the store
@@ -26,6 +27,7 @@ Feature: Adding a new product with an integer attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
+ And I add the "Weight" attribute to it
And I set its non-translatable "Weight" attribute to 10
And I add it
Then I should be notified that it has been successfully created
diff --git a/features/admin/product/managing_products/adding_product_with_percent_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature
similarity index 91%
rename from features/admin/product/managing_products/adding_product_with_percent_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature
index 7063880eb2..cd85a2dca0 100644
--- a/features/admin/product/managing_products/adding_product_with_percent_attribute.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature
@@ -15,7 +15,8 @@ Feature: Adding a new product with a percent attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
- And I set its "Awesomeness rating" attribute to 80 in "English (United States)"
+ And I add the "Awesomeness rating" attribute to it
+ And I set the "Awesomeness rating" attribute value to 80 in "English (United States)"
And I add it
Then I should be notified that it has been successfully created
And the product "44 Magnum" should appear in the store
@@ -26,6 +27,7 @@ Feature: Adding a new product with a percent attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
+ And I add the "Accuracy" attribute to it
And I set its non-translatable "Accuracy" attribute to 95
And I add it
Then I should be notified that it has been successfully created
diff --git a/features/admin/product/managing_products/adding_product_with_select_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature
similarity index 98%
rename from features/admin/product/managing_products/adding_product_with_select_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature
index f4b75295ac..57930df3a0 100644
--- a/features/admin/product/managing_products/adding_product_with_select_attribute.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature
@@ -9,7 +9,7 @@ Feature: Adding a new product with a select attribute
And the store has a non-translatable select product attribute "Mug material" with value "Ceramic"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a product with a select attribute with choices in different locales
When I want to create a new configurable product
And I specify its code as "mug"
diff --git a/features/admin/product/managing_products/adding_product_with_text_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature
similarity index 85%
rename from features/admin/product/managing_products/adding_product_with_text_attribute.feature
rename to features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature
index c4ceea69c5..1de5f95905 100644
--- a/features/admin/product/managing_products/adding_product_with_text_attribute.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature
@@ -16,7 +16,8 @@ Feature: Adding a new product with text attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
- And I set its "Gun caliber" attribute to "11 mm" in "English (United States)"
+ And I add the "Gun caliber" attribute
+ And I set the "Gun caliber" attribute value to "11 mm" in "English (United States)"
And I add it
Then I should be notified that it has been successfully created
And the product "44 Magnum" should appear in the store
@@ -27,6 +28,7 @@ Feature: Adding a new product with text attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
+ And I add the "Author" attribute to it
And I set its non-translatable "Author" attribute to "Colt"
And I add it
Then I should be notified that it has been successfully created
@@ -38,8 +40,10 @@ Feature: Adding a new product with text attribute
When I want to create a new configurable product
And I specify its code as "44_MAGNUM"
And I name it "44 Magnum" in "English (United States)"
- And I set its "Gun caliber" attribute to "11 mm" in "English (United States)"
- And I set its "Overall length" attribute to "30.5 cm" in "English (United States)"
+ And I add the "Gun caliber" attribute
+ And I set the "Gun caliber" attribute value to "11 mm" in "English (United States)"
+ And I add the "Overall length" attribute
+ And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)"
And I remove its "Gun caliber" attribute
And I add it
Then I should be notified that it has been successfully created
diff --git a/features/admin/product/managing_products/adding_select_attribute_in_different_locales.feature b/features/admin/product/managing_products/managing_attributes/adding_select_attribute_in_different_locales.feature
similarity index 100%
rename from features/admin/product/managing_products/adding_select_attribute_in_different_locales.feature
rename to features/admin/product/managing_products/managing_attributes/adding_select_attribute_in_different_locales.feature
diff --git a/features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature b/features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature
similarity index 76%
rename from features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature
rename to features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature
index 04aed9be9e..96589638c7 100644
--- a/features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature
@@ -8,7 +8,7 @@ Feature: Adding text attributes in different locales to a product
Given the store operates on a channel named "Web"
And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales
And it uses the "English (United States)" locale by default
- And the store has a product "Symfony Mug"
+ And the store has a "Symfony Mug" configurable product
And the store has a text product attribute "Mug material"
And I am logged in as an administrator
@@ -17,8 +17,9 @@ Feature: Adding text attributes in different locales to a product
When I want to create a new configurable product
And I specify its code as "mug"
And I name it "PHP Mug" in "English (United States)"
- And I set its "Mug material" attribute to "Wood" in "English (United States)"
- And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)"
+ And I add the "Mug material" attribute
+ And I set the "Mug material" attribute value to "Wood" in "English (United States)"
+ And I set the "Mug material" attribute value to "Drewno" in "Polish (Poland)"
And I add it
Then I should be notified that it has been successfully created
And the product "PHP Mug" should appear in the store
@@ -28,8 +29,9 @@ Feature: Adding text attributes in different locales to a product
@ui @mink:chromedriver @api
Scenario: Adding a text attribute in different locales to an existing product
When I want to modify the "Symfony Mug" product
- And I set its "Mug material" attribute to "Wood" in "English (United States)"
- And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)"
+ And I add the "Mug material" attribute
+ And I set the "Mug material" attribute value to "Wood" in "English (United States)"
+ And I set the "Mug material" attribute value to "Drewno" in "Polish (Poland)"
And I save my changes
Then I should be notified that it has been successfully edited
And attribute "Mug material" of product "Symfony Mug" should be "Wood" in "English (United States)"
diff --git a/features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature b/features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature
similarity index 77%
rename from features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature
rename to features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature
index 37e9a9f3a6..cac95eaddc 100644
--- a/features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature
+++ b/features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature
@@ -6,14 +6,15 @@ Feature: Adding attributes to an existing product
Background:
Given the store operates on a single channel in "United States"
- And the store has a product "44 Magnum"
+ And the store has a "44 Magnum" configurable product
And the store has a text product attribute "Overall length"
And I am logged in as an administrator
@ui @mink:chromedriver @api
Scenario: Adding a text attribute to an existing product
When I want to modify the "44 Magnum" product
- And I set its "Overall length" attribute to "30.5 cm" in "English (United States)"
+ And I add the "Overall length" attribute to it
+ And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)"
And I save my changes
Then I should be notified that it has been successfully edited
And attribute "Overall length" of product "44 Magnum" should be "30.5 cm"
@@ -22,7 +23,8 @@ Feature: Adding attributes to an existing product
Scenario: Adding another text attribute to an existing product
Given this product has a text attribute "Gun caliber" with value "11 mm" in "English (United States)" locale
When I want to modify the "44 Magnum" product
- And I set its "Overall length" attribute to "30.5 cm" in "English (United States)"
+ And I add the "Overall length" attribute to it
+ And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)"
And I save my changes
Then I should be notified that it has been successfully edited
And attribute "Gun caliber" of product "44 Magnum" should be "11 mm"
@@ -31,7 +33,8 @@ Feature: Adding attributes to an existing product
@ui @mink:chromedriver @api
Scenario: Adding and removing text attributes on product update page
When I want to modify the "44 Magnum" product
- And I set its "Overall length" attribute to "30.5 cm" in "English (United States)"
+ And I add the "Overall length" attribute to it
+ And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)"
And I remove its "Overall length" attribute
And I save my changes
Then I should be notified that it has been successfully edited
@@ -41,7 +44,8 @@ Feature: Adding attributes to an existing product
Scenario: Adding and removing after saving text attributes on product update page
Given this product has a text attribute "Gun caliber" with value "11 mm" in "English (United States)" locale
When I want to modify the "44 Magnum" product
- And I set its "Overall length" attribute to "30.5 cm" in "English (United States)"
+ And I add the "Overall length" attribute to it
+ And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)"
And I save my changes
And I remove its "Gun caliber" attribute
And I save my changes
diff --git a/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature b/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature
index cf0f4fc3a4..3e31ed4795 100644
--- a/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature
+++ b/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature
@@ -12,13 +12,13 @@ Feature: Modifying taxons assigned to an existing product
And the product "T-Shirt" belongs to taxon "Clothes"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Modifying taxons assigned to a product
When I change that the "T-Shirt" product does not belong to the "Clothes" taxon
And I add "T-Shirts" taxon to the "T-Shirt" product
Then the product "T-Shirt" should have the "T-Shirts" taxon
- @ui @api
+ @todo @ui @api
Scenario: Adding taxons to product
When I add "Clothes" taxon to the "Shirt" product
Then the product "Shirt" should have the "Clothes" taxon
diff --git a/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature b/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature
index 8cad82456b..89141b3a1d 100644
--- a/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature
+++ b/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature
@@ -14,13 +14,13 @@ Feature: Preventing deletion of purchased product
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Purchased product cannot be deleted
When I try to delete the "Toyota GT86 model" product
Then I should be notified that this product is in use and cannot be deleted
And this product should still exist in the product catalog
- @ui @api
+ @todo @ui @api
Scenario: Purchased product images should be kept
Given the store has a product "Lamborghini Gallardo Model"
And this product has an image "lamborghini.jpg" with "thumbnail" type
diff --git a/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature b/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature
index 8ab868842a..4a71b8fc5a 100644
--- a/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature
+++ b/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature
@@ -10,12 +10,12 @@ Feature: Preventing a potential XSS attack while adding a new product
And the store has "No XSS" taxonomy
And I am logged in as an administrator
- @ui @javascript @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Preventing a potential XSS attack while adding new product
When I want to create a new simple product
Then I should be able to name it "No XSS" in "English (United States)"
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Preventing a potential XSS attack while choosing main taxon for a new product
When I want to create a new simple product
Then I should be able to choose main taxon "No XSS"
diff --git a/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature b/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature
index 2b058d1544..491591b508 100644
--- a/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature
+++ b/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature
@@ -10,7 +10,7 @@ Feature: Preventing a potential XSS attack while selecting similar product
And the store has "" and "LG headphones" products
And I am logged in as an administrator
- @ui @javascript @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Preventing a potential XSS attack while editing product
When I want to create a new simple product
Then I should be able to associate as "Accessories" the "LG headphones" product
diff --git a/features/admin/product/managing_products/product_validation.feature b/features/admin/product/managing_products/product_validation.feature
index b3f8a896f6..25370a1b30 100644
--- a/features/admin/product/managing_products/product_validation.feature
+++ b/features/admin/product/managing_products/product_validation.feature
@@ -13,7 +13,7 @@ Feature: Products validation
And this product attribute has set min value as 3 and max value as 30
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product without specifying its code
When I want to create a new simple product
And I name it "Dice Brewing" in "English (United States)"
@@ -29,7 +29,7 @@ Feature: Products validation
And I try to save my changes
Then I should be notified that the locale is not available
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product with duplicated code among products
Given the store has a product "7 Wonders" with code "AWESOME_GAME"
When I want to create a new simple product
@@ -40,7 +40,7 @@ Feature: Products validation
Then I should be notified that code has to be unique
And product with name "Dice Brewing" should not be added
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product with duplicated code among product variants
Given the store has a product "7 Wonders"
And this product has "7 Wonders: Cities" variant priced at "$30.00" identified by "AWESOME_GAME"
@@ -52,7 +52,7 @@ Feature: Products validation
Then I should be notified that simple product code has to be unique
And product with name "Dice Brewing" should not be added
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product without specifying its slug
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -63,7 +63,7 @@ Feature: Products validation
Then I should be notified that slug is required
And product with name "Dice Brewing" should not be added
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product without specifying its name
When I want to create a new simple product
And I specify its code as "BOARD_DICE_BREWING"
@@ -72,7 +72,7 @@ Feature: Products validation
Then I should be notified that name is required
And product with code "BOARD_DICE_BREWING" should not be added
- @ui @no-api
+ @todo @ui @no-api
Scenario: Adding a new simple product without specifying its price for every channel
Given the store operates on another channel named "Web-GB"
When I want to create a new simple product
@@ -85,7 +85,7 @@ Feature: Products validation
Then I should be notified that price must be defined for every channel
And product with code "BOARD_DICE_BREWING" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Adding a new configurable product without specifying its code
When I want to create a new configurable product
And I name it "Dice Brewing" in "English (United States)"
@@ -93,7 +93,7 @@ Feature: Products validation
Then I should be notified that code is required
And product with name "Dice Brewing" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Adding a new configurable product with too long code
When I want to create a new configurable product
And I name it "Dice Brewing" in "English (United States)"
@@ -101,7 +101,7 @@ Feature: Products validation
And I try to add it
Then I should be notified that code is too long
- @ui @api
+ @todo @ui @api
Scenario: Adding a new configurable product with duplicated code
Given the store has a product "7 Wonders" with code "AWESOME_GAME"
When I want to create a new configurable product
@@ -111,7 +111,7 @@ Feature: Products validation
Then I should be notified that code has to be unique
And product with name "Dice Brewing" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Adding a new configurable product without specifying its name
When I want to create a new configurable product
And I specify its code as "BOARD_DICE_BREWING"
@@ -120,7 +120,7 @@ Feature: Products validation
Then I should be notified that name is required
And product with code "BOARD_DICE_BREWING" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to set too long meta keywords for a product
Given the store has a "Dice Brewing" product
When I want to modify this product
@@ -128,7 +128,7 @@ Feature: Products validation
And I try to save my changes
Then I should be notified that meta keywords are too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to set too long meta keywords for a product
Given the store has a "Dice Brewing" product
When I want to modify this product
@@ -136,7 +136,7 @@ Feature: Products validation
And I try to save my changes
Then I should be notified that meta description is too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove name from existing product
Given the store has a "Dice Brewing" product
When I want to modify this product
@@ -145,7 +145,7 @@ Feature: Products validation
Then I should be notified that name is required
And this product should still be named "Dice Brewing"
- @ui @api
+ @todo @ui @api
Scenario: Trying to assign new channel to an existing configurable product without specifying its all variant prices for this channel
Given the store has a "7 Wonders" configurable product
And this product has "7 Wonders: Cities" variant priced at "$30.00"
@@ -156,7 +156,7 @@ Feature: Products validation
And I save my changes
Then I should be notified that I have to define product variants' prices for newly assigned channels first
- @ui @api
+ @todo @ui @api
Scenario: Adding a new product with duplicated slug
Given the store has a "7 Wonders" configurable product with "7-wonders" slug
When I want to create a new configurable product
@@ -167,7 +167,7 @@ Feature: Products validation
Then I should be notified that slug has to be unique
And product with code "7-WONDERS-BABEL" should not be added
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Trying to add a new product with a text attribute without specifying its value in default locale
When I want to create a new configurable product
And I specify its code as "X-18-MUG"
@@ -178,7 +178,7 @@ Feature: Products validation
Then I should be notified that I have to define the "Mug material" attribute in "English (United States)"
And product with code "X-18-MUG" should not be added
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Trying to add a new product with a text attribute without specifying its value in additional locale with proper length
When I want to create a new configurable product
And I specify its code as "X-18-MUG"
@@ -189,7 +189,7 @@ Feature: Products validation
Then I should be notified that the "Mug material" attribute in "Polish (Poland)" should be longer than 3
And product with code "X-18-MUG" should not be added
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Trying to add a text attribute in different locales to an existing product without specifying its value in default locale
When I want to modify the "Symfony Mug" product
And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)"
@@ -197,7 +197,7 @@ Feature: Products validation
And I save my changes
Then I should be notified that I have to define the "Mug material" attribute in "English (United States)"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Trying to add a text attribute in different locales to an existing product without specifying its value in additional locale with proper length
When I want to modify the "Symfony Mug" product
And I set its "Mug material" attribute to "Dr" in "Polish (Poland)"
diff --git a/features/admin/product/managing_products/removing_images_of_product.feature b/features/admin/product/managing_products/removing_images_of_product.feature
index 3f9aa42f14..3947e32a5b 100644
--- a/features/admin/product/managing_products/removing_images_of_product.feature
+++ b/features/admin/product/managing_products/removing_images_of_product.feature
@@ -6,6 +6,7 @@ Feature: Removing images of an existing product
Background:
Given I am logged in as an administrator
+ And the store operates on a single channel
@ui @mink:chromedriver @api
Scenario: Removing a single image of a simple product
diff --git a/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature b/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature
index 63569065b2..86f15a91f3 100644
--- a/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature
+++ b/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature
@@ -12,7 +12,7 @@ Feature: Removing a product's price after channel deletion
And this product is also priced at "£5.00" in "Web-GB" channel
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Removing a product's price after corresponding channel deletion
When channel "Web-GB" has been deleted
Then product "Dice Brewing" should be priced at $10.00 for channel "Web-US"
diff --git a/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature b/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature
index baa7681125..0a56dbfcad 100644
--- a/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature
+++ b/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature
@@ -13,7 +13,7 @@ Feature: Removing a product's price from the channel where it is not available i
And this product is disabled in "Web-GB" channel
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Removing a product's price from disabled channel
Given the channel "Web-GB" has been disabled
When I want to modify the "Dice Brewing" product
@@ -22,7 +22,7 @@ Feature: Removing a product's price from the channel where it is not available i
Then I should not have configured price for "Web-GB" channel
But I should have original price equal to "£70.00" in "Web-GB" channel
- @ui @no-api
+ @todo @ui @no-api
Scenario: Removing a product's price from obsolete channel
Given this product is disabled in "Web-GB" channel
When I want to modify the "Dice Brewing" product
diff --git a/features/admin/product/managing_products/select_taxons_for_new_product.feature b/features/admin/product/managing_products/select_taxons_for_new_product.feature
index c063c64922..e152c046a8 100644
--- a/features/admin/product/managing_products/select_taxons_for_new_product.feature
+++ b/features/admin/product/managing_products/select_taxons_for_new_product.feature
@@ -10,7 +10,7 @@ Feature: Select taxon for a new product
And I am logged in as an administrator
And I am using "English (United Kingdom)" locale for my panel
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Specifying main taxon for configurable product
When I want to create a new configurable product
And I choose main taxon "Sad"
@@ -21,7 +21,7 @@ Feature: Select taxon for a new product
Then I should be notified that it has been successfully created
And main taxon of product "Gentleman Jack" should be "Sad"
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Specifying main taxon for simple product
When I want to create a new simple product
And I choose main taxon "Sad"
diff --git a/features/admin/product/managing_products/select_taxons_for_product.feature b/features/admin/product/managing_products/select_taxons_for_product.feature
index 1fdc8ec416..f2ca69633a 100644
--- a/features/admin/product/managing_products/select_taxons_for_product.feature
+++ b/features/admin/product/managing_products/select_taxons_for_product.feature
@@ -12,7 +12,7 @@ Feature: Select taxon for an existing product
And I am logged in as an administrator
And I am using "English (United Kingdom)" locale for my panel
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Specifying main taxon for configurable product
When I want to modify the "T-Shirt Banana" product
And I choose main taxon "T-Shirts"
@@ -20,11 +20,10 @@ Feature: Select taxon for an existing product
Then I should be notified that it has been successfully edited
And main taxon of product "T-Shirt Banana" should be "T-Shirts"
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Specifying main taxon for simple product
When I want to modify the "T-Shirt Batman" product
And I choose main taxon "Sad"
And I save my changes
Then I should be notified that it has been successfully edited
And main taxon of product "T-Shirt Batman" should be "Sad"
-
diff --git a/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature b/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature
index 00f5743882..e24d914606 100644
--- a/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature
+++ b/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature
@@ -17,7 +17,7 @@ Feature: Selecting main taxon for product in different locales
And the store has a product "T-Shirt Batman"
And I am logged in as an administrator
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Choosing only taxons from the Polish locale
Given I am using "Polish (Poland)" locale for my panel
When I want to choose main taxon for product "T-Shirt Batman"
@@ -25,7 +25,7 @@ Feature: Selecting main taxon for product in different locales
And I should be able to choose taxon "Woman-T-Shirts_PL" from the list
And I should not be able to choose taxon "Woman-T-Shirts_UA" from the list
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Choosing only taxons from the French locale
Given I am using "French (France)" locale for my panel
When I want to choose main taxon for product "T-Shirt Batman"
@@ -33,7 +33,7 @@ Feature: Selecting main taxon for product in different locales
And I should be able to choose taxon "Woman-T-Shirts_FR" from the list
And I should not be able to choose taxon "Woman-T-Shirts_UA" from the list
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Choosing only taxons from the German locale
Given I am using "German (Germany)" locale for my panel
When I want to choose main taxon for product "T-Shirt Batman"
diff --git a/features/admin/product/managing_products/sorting_products.feature b/features/admin/product/managing_products/sorting_products.feature
index 6e1b076594..eb38f7fbb8 100644
--- a/features/admin/product/managing_products/sorting_products.feature
+++ b/features/admin/product/managing_products/sorting_products.feature
@@ -16,14 +16,14 @@ Feature: Sorting listed products
And this product is named "Ekstremalny Mops" in the "Polish" locale
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Products are sorted by ascending codes by default
Given I am browsing products
Then I should see 3 products in the list
And I should see a product with code "L_PUG"
But the first product on the list should have code "B_PUG"
- @ui @api
+ @todo @ui @api
Scenario: Changing the codes sorting order
Given I am browsing products
When I switch the way products are sorted descending by code
@@ -31,7 +31,7 @@ Feature: Sorting listed products
And I should see a product with code "B_PUG"
But the first product on the list should have code "X_PUG"
- @ui @api
+ @todo @ui @api
Scenario: Products can be sorted by their names
Given I am browsing products
When I start sorting products by name
@@ -39,7 +39,7 @@ Feature: Sorting listed products
And I should see a product with name "Xtreme Pug"
But the first product on the list should have name "Berserk Pug"
- @ui @api
+ @todo @ui @api
Scenario: Changing the names sorting order
Given I am browsing products
When the products are already sorted ascending by name
@@ -48,7 +48,7 @@ Feature: Sorting listed products
And I should see a product with name "Berserk Pug"
But the first product on the list should have name "Xtreme Pug"
- @ui @api
+ @todo @ui @api
Scenario: Sort products ascending by name from chosen locale translations
When I change my locale to "Polish (Poland)"
And I browse products
@@ -56,7 +56,7 @@ Feature: Sorting listed products
Then I should see 3 products in the list
And the first product on the list should have name "Ekstremalny Mops"
- @ui @api
+ @todo @ui @api
Scenario: Sort products descending by name from chosen locale translations
When I change my locale to "Polish (Poland)"
And I browse products
@@ -65,7 +65,7 @@ Feature: Sorting listed products
Then I should see 3 products in the list
And the first product on the list should have name "Szałowy Mops"
- @ui @api @no-postgres
+ @todo @ui @api @no-postgres
Scenario: Missing translations are sorted as first when sorting by name ascending
When I change my locale to "Polish"
And I browse products
@@ -74,7 +74,7 @@ Feature: Sorting listed products
And the first product on the list shouldn't have a name
And the last product on the list should have name "Ekstremalny Mops"
- @ui @api @no-postgres
+ @todo @ui @api @no-postgres
Scenario: Missing translation are sorted as last when sorting by name descending
When I change my locale to "Polish"
And I browse products
diff --git a/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature b/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature
index 0e9c3496b2..79a4bc039f 100644
--- a/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature
+++ b/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature
@@ -29,7 +29,7 @@ Feature: Sorting listed products from a taxon by position
And the store has a product "Ultimate Pug" in the "Soft Toys" taxon at 19th position
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to position -1 on the non-last page
When I am browsing the 1st page of products from "Soft Toys" taxon
And I set the position of "Old pug" to "-1"
@@ -39,7 +39,7 @@ Feature: Sorting listed products from a taxon by position
Then the one before last product on the list should have name "Old pug" with position 18
And the last product on the list should have name "Young pug" with position 19
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to position -1 on the last page
When I am browsing the 2nd page of products from "Soft Toys" taxon
And I set the position of "Pug XL" to "-1"
@@ -48,7 +48,7 @@ Feature: Sorting listed products from a taxon by position
Then the one before last product on the list should have name "Pug XL" with position 18
And the last product on the list should have name "Pug XS" with position 19
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to the already occupied position on the other page
When I am browsing the 1st page of products from "Soft Toys" taxon
And I set the position of "Old pug" to "15"
@@ -64,7 +64,7 @@ Feature: Sorting listed products from a taxon by position
And the 7th product on this page should be named "Pug Master"
And this product should be at position 16
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to the already occupied position on the same page
When I am browsing the 2nd page of products from "Soft Toys" taxon
And I set the position of "Puglet" to "15"
@@ -80,7 +80,7 @@ Feature: Sorting listed products from a taxon by position
And the 7th product on this page should be named "Pug Master"
And this product should be at position 16
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to the positions overflowing the max available position on the non-last page
When I am browsing the 1st page of products from "Soft Toys" taxon
And I set the position of "Old pug" to "25"
@@ -90,7 +90,7 @@ Feature: Sorting listed products from a taxon by position
Then the one before last product on the list should have name "Old pug" with position 18
And the last product on the list should have name "Young pug" with position 19
- @ui @no-api
+ @todo @ui @no-api
Scenario: Setting two products to the positions overflowing the max available position on the last page
When I am browsing the 2nd page of products from "Soft Toys" taxon
And I set the position of "Puglet" to "25"
@@ -100,14 +100,14 @@ Feature: Sorting listed products from a taxon by position
Then the one before last product on the list should have name "Puglet" with position 18
And the last product on the list should have name "Pug XL" with position 19
- @ui @api
+ @todo @ui @api
Scenario: New product is added as last one
Given I added a product "Big pug"
And I assigned this product to "Soft Toys" taxon
When I am browsing the 3rd page of products from "Soft Toys" taxon
Then the last product on the list within this taxon should have name "Big pug"
- @ui @api
+ @todo @ui @api
Scenario: Product with position 0 is set as the first one
When I am browsing products from "Soft Toys" taxon
And I set the position of "Young pug" to 0
@@ -115,20 +115,20 @@ Feature: Sorting listed products from a taxon by position
And I go to the 1st page of products from "Soft Toys" taxon
Then the first product on the list within this taxon should have name "Young pug"
- @ui @api
+ @todo @ui @api
Scenario: Being unable to use a non-numeric string as a product position
Given I am browsing products from "Soft Toys" taxon
When I set the position of "Young pug" to "test"
And I save my new configuration
Then I should be notified that the position "test" is invalid
- @ui @api
+ @todo @ui @api
Scenario: Sort products in descending order
When I am browsing products from "Soft Toys" taxon
And I sort this taxon's products "descending" by "position"
Then the first product on the list within this taxon should have name "Ultimate Pug"
- @ui @api
+ @todo @ui @api
Scenario: Products are sorted by position in ascending order by default
When I am browsing products from "Soft Toys" taxon
Then the first product on the list within this taxon should have name "Old pug"
diff --git a/features/admin/product/managing_products/toggling_inventory_on_product.feature b/features/admin/product/managing_products/toggling_inventory_on_product.feature
index 79d54d924d..4724f797ab 100644
--- a/features/admin/product/managing_products/toggling_inventory_on_product.feature
+++ b/features/admin/product/managing_products/toggling_inventory_on_product.feature
@@ -8,7 +8,7 @@ Feature: Toggling the inventory tracking
Given the store has a product "Dice Brewing"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Disabling inventory for a simple product
Given the "Dice Brewing" product is tracked by the inventory
When I want to modify the "Dice Brewing" product
@@ -17,7 +17,7 @@ Feature: Toggling the inventory tracking
Then I should be notified that it has been successfully edited
And inventory of this product should not be tracked
- @ui @no-api
+ @todo @ui @no-api
Scenario: Enabling inventory for a simple product
When I want to modify the "Dice Brewing" product
And I enable its inventory tracking
diff --git a/features/admin/product/managing_products/toggling_product.feature b/features/admin/product/managing_products/toggling_product.feature
index cc8bd11389..a1666fd14b 100644
--- a/features/admin/product/managing_products/toggling_product.feature
+++ b/features/admin/product/managing_products/toggling_product.feature
@@ -8,7 +8,7 @@ Feature: Toggling the simple product
Given the store has a product "Dice Brewing"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Disabling a simple product
Given the "Dice Brewing" product is enabled
When I want to modify the "Dice Brewing" product
@@ -17,7 +17,7 @@ Feature: Toggling the simple product
Then I should be notified that it has been successfully edited
And this product should be disabled along with its variant
- @ui @no-api
+ @todo @ui @no-api
Scenario: Enabling a simple product
Given the "Dice Brewing" product is disabled
When I want to modify the "Dice Brewing" product
diff --git a/features/admin/product/managing_products/viewing_non_translatable_attributes.feature b/features/admin/product/managing_products/viewing_non_translatable_attributes.feature
index 5a5387fcb9..9324fdfe33 100644
--- a/features/admin/product/managing_products/viewing_non_translatable_attributes.feature
+++ b/features/admin/product/managing_products/viewing_non_translatable_attributes.feature
@@ -10,7 +10,7 @@ Feature: Viewing product's non translatable attributes on edit page
And this product has non-translatable percent attribute "crit chance" with value 10%
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Viewing product's attributes defined in different locales
When I modify the "Iron Pickaxe" product
And I should see non-translatable attribute "crit chance" with value 10%
diff --git a/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature b/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature
index d17de228b8..fa0cda88d6 100644
--- a/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature
+++ b/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature
@@ -8,7 +8,7 @@ Feature: Seeing the correct catalog price history after creating a product varia
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing historical product variant prices after the product variant has been created without any promotion applied
Given the store has a "Wyborowa Vodka" configurable product
When I want to create a new variant of this product
@@ -20,7 +20,7 @@ Feature: Seeing the correct catalog price history after creating a product varia
Then I should see a single log entry in the catalog price history
And there should be a log entry with the "$20.00" selling price, "$25.00" original price and datetime of the price change
- @api @ui
+ @api @todo @ui
Scenario: Seeing historical product variant prices after the product variant has been created without original price and any promotion applied
Given the store has a "Wyborowa Vodka" configurable product
When I want to create a new variant of this product
@@ -31,7 +31,7 @@ Feature: Seeing the correct catalog price history after creating a product varia
Then I should see a single log entry in the catalog price history
And there should be a log entry with the "$20.00" selling price, no original price and datetime of the price change
- @api @ui
+ @api @todo @ui
Scenario: Seeing historical product variant prices after the product variant has been created with catalog promotions applied
Given the store has a "Wyborowa Vodka" configurable product
And there is a catalog promotion "Christmas sale" that reduces price by "50%" and applies on "Wyborowa Vodka" product
diff --git a/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature b/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature
index 132773200f..c670c22dce 100644
--- a/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature
+++ b/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature
@@ -9,7 +9,7 @@ Feature: Seeing the correct catalog price history after editing a product varian
And the store has a product "Wyborowa Vodka" priced at "$40.00" in "United States" channel
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing historical product variant prices after the product variant has been edited
When I want to modify the "Wyborowa Vodka" product variant
And I change its price to "$42.00" for "United States" channel
diff --git a/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature b/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature
index a13185f909..707c012530 100644
--- a/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature
+++ b/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature
@@ -13,7 +13,7 @@ Feature: Seeing the price history of a simple product after changes to catalog p
And it reduces price by "90%"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing the catalog price history of a simple product
Given the "Winter sale" catalog promotion is enabled
When I disable "Winter sale" catalog promotion
@@ -23,7 +23,7 @@ Feature: Seeing the price history of a simple product after changes to catalog p
And there should be a log entry on the 2nd position with the "$10.00" selling price, "$100.00" original price and datetime of the price change
And there should be a log entry on the 3rd position with the "$100.00" selling price, no original price and datetime of the price change
- @api @ui
+ @api @todo @ui
Scenario: Seeing the catalog price history of a simple product with a price different than an original price
Given "Wyborowa Vodka" variant is originally priced at "$120.00" in "United States" channel
And the "Winter sale" catalog promotion is enabled
diff --git a/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature b/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature
index 16c52b3320..877f446400 100644
--- a/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature
@@ -12,13 +12,13 @@ Feature: Accessing to product edit page from show page
And I am logged in as an administrator
And I am browsing products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing to product edit page from product show page
When I access the "Iron Shield" product
And I go to edit page
Then I should be on "Iron shield" product edit page
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing to variant edit page from product show page
When I access the "Iron Shield" product
And I go to edit page of "Iron shield - very big" variant
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature
index af103dfa62..8f323cf4e7 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature
@@ -15,7 +15,7 @@ Feature: Seeing applied catalog promotions details for a simple product
And I am logged in as an administrator
And I am browsing products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing applied catalog promotion details on a simple product
When I access "Ursus C-355" product
Then this product price should be decreased by catalog promotion "Company bankruptcy sale" in "United States" channel
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature
index 8994cca64e..89afc6c773 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature
@@ -22,7 +22,7 @@ Feature: Seeing applied catalog promotions details within variant
And I am logged in as an administrator
And I am browsing products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing applied catalog promotion details within variant
When I access "Wyborowa Vodka" product
Then "Wyborowa Vodka Exquisite" variant price should be decreased by catalog promotion "Winter sale" in "United States" channel
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature
index e8844bf412..6fcc443a88 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature
@@ -17,13 +17,13 @@ Feature: Viewing details of a product with variants
And I am logged in as an administrator
And I am browsing products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing a configurable product
When I access the "Iron Shield" product
Then I should see product show page with variants
And I should see product name "Iron Shield"
- @ui @api
+ @todo @ui @api
Scenario: Viewing taxonomies
Given the store classifies its products as "Shield" and "Equipment"
And the product "Iron Shield" has a main taxon "Equipment"
@@ -32,32 +32,32 @@ Feature: Viewing details of a product with variants
Then I should see main taxon is "Equipment"
And I should see product taxon "Shield"
- @ui @api
+ @todo @ui @api
Scenario: Viewing options
When I access the "Iron Shield" product
Then I should see option "Shield size"
- @ui @api
+ @todo @ui @api
Scenario: Viewing variants
When I access the "Iron Shield" product
Then I should see 2 variants
And I should see the "Iron Shield - very big" variant
And I should see the "Iron Shield - very small" variant
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing variants' details
When I access the "Iron Shield" product
Then I should see 2 variants
And I should see "Iron Shield - very big" variant with code "123456789-xl", priced "$25.00" and current stock 5 and in "United States" channel
And I should see "Iron Shield - very small" variant with code "123456789-xs", priced "$15.00" and current stock 12 and in "United States" channel
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Viewing media
Given the "Iron Shield" product has an image "mugs.jpg" with "main" type
When I access the "Iron Shield" product
Then I should see an image related to this product
- @ui @api
+ @todo @ui @api
Scenario: Viewing more details
Given the product "Iron Shield" has the slug "iron-shield"
And the description of product "Iron Shield" is "Shield created by dwarf"
@@ -70,14 +70,14 @@ Feature: Viewing details of a product with variants
And I should see product's meta keywords is "shield"
And I should see product's short description is "good shield"
- @ui @api
+ @todo @ui @api
Scenario: Viewing association types
Given the store has a "Glass shield" product
And the product "Iron Shield" has an association "Similar" with product "Glass shield"
When I access the "Iron Shield" product
Then I should see product association type "Similar"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing associations
Given the store has a "Glass shield" product
And the product "Iron Shield" has an association "Similar" with product "Glass shield"
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature
index 71de4aff4a..fc4bbcdf8a 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature
@@ -11,21 +11,21 @@ Feature: Viewing details of a simple product
And I am logged in as an administrator
And I am browsing products
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing a simple product show page
When I access the "Iron Shield" product
Then I should see product show page without variants
And I should see product name "Iron Shield"
And I should see product breadcrumb "Iron Shield"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing pricing block
Given the product "Iron Shield" has original price "$25.00"
When I access the "Iron Shield" product
Then I should see price "$20.00" for channel "United States"
And I should see original price "$25.00" for channel "United States"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing price block without channel enable
Given this product is unavailable in "United States" channel
When I access the "Iron Shield" product
@@ -33,7 +33,7 @@ Feature: Viewing details of a simple product
And I should see the product in neither channel
And I should not see price for channel "United States"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing details block
Given the store has a tax category "No tax" with a code "nt"
And product's "Iron Shield" code is "123456789"
@@ -45,7 +45,7 @@ Feature: Viewing details of a simple product
And I should see 4 as a current stock of this product
And I should see product's tax category is "No tax"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing taxonomy block
Given this product belongs to "Shield"
And the product "Iron Shield" has a main taxon "Equipment"
@@ -53,7 +53,7 @@ Feature: Viewing details of a simple product
Then I should see main taxon is "Equipment"
And I should see product taxon "Shield"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing shipping block
Given the store has "Over sized" and "Standard" shipping category
And the product "Iron Shield" has height "10.0", width "15.0", depth "20.0", weight "25.0"
@@ -65,13 +65,13 @@ Feature: Viewing details of a simple product
And I should see product's depth is 20
And I should see product's weight is 25
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Viewing media block
Given the "Iron Shield" product has an image "mugs.jpg" with "main" type
When I access the "Iron Shield" product
Then I should see an image related to this product
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing "more details" block
Given the product "Iron Shield" has the slug "iron-shield"
And the description of product "Iron Shield" is "Shield created by dwarf"
@@ -84,7 +84,7 @@ Feature: Viewing details of a simple product
And I should see product's meta keywords is "shield"
And I should see product's short description is "good shield"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Viewing associations block
Given the store has "Similar" and "Dwarf equipment" product association types
And the store has a "Glass Shield" product
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature
index ebff161863..74264d3138 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature
@@ -14,7 +14,7 @@ Feature: Viewing product's non translatable attributes
And I am logged in as an administrator
And I am browsing products
- @ui @api
+ @todo @ui @api
Scenario: Viewing product's non translatable attributes along with default ones
When I access the "Iron Pickaxe" product
Then I should see non-translatable attribute "crit chance" with value 10%
diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature
index 7d00084b0a..7d072f76f0 100644
--- a/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature
+++ b/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature
@@ -15,7 +15,7 @@ Feature: Viewing product's attributes in different locales
And I am logged in as an administrator
And I am browsing products
- @ui @api
+ @todo @ui @api
Scenario: Viewing product's attributes defined in different locales
When I access the "Iron Shield" product
Then I should see attribute "material" with value "oak wood" in "English (United States)" locale
diff --git a/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature b/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature
index b22fab3432..ff90ba9abe 100644
--- a/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature
+++ b/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature
@@ -8,7 +8,7 @@ Feature: Adding a new catalog promotion with fixed discount where amount is a de
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @no-api @javascript
+ @ui @no-api @mink:chromedriver
Scenario: Adding a new catalog promotion with fixed discount and amount with comma
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
diff --git a/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature b/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature
index 5123815443..9660945f2d 100644
--- a/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature
+++ b/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature
@@ -15,27 +15,27 @@ Feature: Browsing variants affected by catalog promotions
And this product has "Sylius T-Shirt" variant priced at "$15.00"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing product variants affected by a catalog promotion applied on variants
Given there is a catalog promotion "PHP T-Shirt promotion" that reduces price by "50%" and applies on "PHP T-Shirt" variant
When I browse variants affected by catalog promotion "PHP T-Shirt promotion"
Then there should be 1 product variant on the list
And it should be the "PHP T-Shirt" product variant
- @ui @api
+ @todo @ui @api
Scenario: Browsing product variants affected by a catalog promotion applied on products
Given there is a catalog promotion "T-Shirt promotion" that reduces price by "20%" and applies on "T-Shirt" product
When I browse variants affected by catalog promotion "T-Shirt promotion"
Then there should be 2 product variants on the list
And it should be "PHP T-Shirt" and "Sylius T-Shirt" product variants
- @ui @api
+ @todo @ui @api
Scenario: Browsing product variants affected by a catalog promotion applied on taxons
Given there is a catalog promotion "Clothes promotion" that reduces price by "10%" and applies on "Clothes" taxon
When I browse variants affected by catalog promotion "Clothes promotion"
Then there should be 3 product variants on the list
- @ui @api
+ @todo @ui @api
Scenario: Browsing product variants affected by a catalog promotion when its scope overlaps with an exclusive promotion
Given there is a catalog promotion "T-Shirt promotion" that reduces price by "20%" and applies on "T-Shirt" product
And there is an exclusive catalog promotion "Sylius T-Shirt promotion" with priority 100 that reduces price by "30%" and applies on "Sylius T-Shirt" variant
@@ -43,7 +43,7 @@ Feature: Browsing variants affected by catalog promotions
Then there should be 1 product variant on the list
And it should be the "PHP T-Shirt" product variant
- @ui @no-api
+ @todo @ui @no-api
Scenario: Accessing the product details page through affected product variants list
Given there is a catalog promotion "PHP T-Shirt promotion" that reduces price by "50%" and applies on "PHP T-Shirt" variant
When I browse variants affected by catalog promotion "PHP T-Shirt promotion"
diff --git a/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature
index 970e040b28..2a5a0b4e07 100644
--- a/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature
+++ b/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature
@@ -140,8 +140,8 @@ Feature: Creating a catalog promotion
Then the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$9.45" with 3 promotions
And the visitor should see that the "Kotlin T-Shirt" variant is discounted from "$40.00" to "$30.00" with "Winter sale" promotion
- @ui @javascript
- Scenario: Adding a new catalog promotion of default type with one action
+ @ui @mink:chromedriver @no-api
+ Scenario: Adding a new catalog promotion with one scope and one action
When I want to create a new catalog promotion
And I add a new catalog promotion scope
And I add a new catalog promotion action
diff --git a/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature
index a5b4845c36..7d992feae4 100644
--- a/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature
+++ b/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature
@@ -50,14 +50,20 @@ Feature: Editing catalog promotion
@api @ui @mink:chromedriver
Scenario: Editing catalog promotion variant scope
- When I edit "Christmas sale" catalog promotion to be applied on "Kotlin T-Shirt" variant
+ When I want to modify a catalog promotion "Christmas sale"
+ And I remove "PHP T-Shirt" variant from its scope
+ And I add "Kotlin T-Shirt" variant to its scope
+ And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should be applied on "Kotlin T-Shirt" variant
And this catalog promotion should not be applied on "PHP T-Shirt" variant
@api @ui @mink:chromedriver
Scenario: Editing catalog promotion taxon scope
- When I edit "Christmas sale" catalog promotion to be applied on "Clothes" taxon
+ When I want to modify a catalog promotion "Christmas sale"
+ And I remove its last scope
+ And I add scope that applies on "Clothes" taxon
+ And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should be applied on "Clothes" taxon
And this catalog promotion should not be applied on "Kotlin T-Shirt" variant
@@ -65,20 +71,28 @@ Feature: Editing catalog promotion
@api @ui @mink:chromedriver
Scenario: Editing catalog promotion product scope
- When I edit "Christmas sale" catalog promotion to be applied on "T-Shirt" product
+ When I want to modify a catalog promotion "Christmas sale"
+ And I remove its last scope
+ And I add scope that applies on "T-Shirt" product
+ And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should be applied on "T-Shirt" product
And this catalog promotion should not be applied on "PHP T-Shirt" variant
@api @ui
Scenario: Editing catalog promotion action
- When I edit "Christmas sale" catalog promotion to have "40%" discount
+ When I want to modify a catalog promotion "Christmas sale"
+ And I edit its action so that it reduces price by "40%"
+ And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should have "40.00%" percentage discount
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Editing catalog promotion action to be a fixed discount
- When I edit "Christmas sale" catalog promotion to have "$10.00" of fixed discount in the "United States" channel
+ When I want to modify a catalog promotion "Christmas sale"
+ When I remove its last action
+ And I add action that gives "$10.00" of fixed discount in the "United States" channel
+ And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should have "$10.00" of fixed discount in the "United States" channel
@@ -101,7 +115,8 @@ Feature: Editing catalog promotion
Scenario: Receiving error message after not filling price for all channels
Given the store operates on another channel named "Poland"
When I want to modify a catalog promotion "Christmas sale"
- And I edit it to have "$10.00" of fixed discount in the "United States" channel
+ When I remove its last action
+ And I add action that gives "$10.00" of fixed discount in the "United States" channel
And I make it available in channel "Poland"
And I save my changes
Then I should be notified that not all channels are filled
@@ -113,7 +128,7 @@ Feature: Editing catalog promotion
And I save my changes
Then I should be notified that the percentage amount should be a number and cannot be empty
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Editing catalog promotion action to be a percentage discount and not filling amount
Given there is a catalog promotion "Winter sale" that reduces price by fixed "$10.00" in the "United States" channel and applies on "T-Shirt" product
When I want to modify a catalog promotion "Christmas sale"
@@ -121,9 +136,10 @@ Feature: Editing catalog promotion
And I save my changes
Then I should be notified that the percentage amount should be a number and cannot be empty
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Editing catalog promotion action to be a fixed discount and not filling amount
- When I want to modify a catalog promotion "Christmas sale"
+ Given there is a catalog promotion "Winter sale" that reduces price by fixed "$10.00" in the "United States" channel and applies on "T-Shirt" product
+ When I want to modify a catalog promotion "Winter sale"
And I edit it to have empty amount of fixed discount in the "United States" channel
And I save my changes
- Then I should be notified that the fixed amount should be a number and cannot be empty
+ Then I should be notified that the fixed amount cannot be empty
diff --git a/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature
index 5f9ce689aa..35b5707765 100644
--- a/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature
+++ b/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature
@@ -17,16 +17,18 @@ Feature: Seeing correct percentage discounts while editing catalog promotion
And it is enabled
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Seeing the accurate percentage amount after editing the catalog promotion including the value up to one decimal place
- When I edit "Christmas sale" catalog promotion to have "2.5%" discount
+ When I want to modify a catalog promotion "Christmas sale"
+ And I edit its action so that it reduces price by "2.5%"
And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should have "2.50%" percentage discount
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Seeing the accurate percentage amount after editing the catalog promotion including the value up to two decimal places
- When I edit "Christmas sale" catalog promotion to have "2.56%" discount
+ When I want to modify a catalog promotion "Christmas sale"
+ And I edit its action so that it reduces price by "2.56%"
And I save my changes
Then I should be notified that it has been successfully edited
And this catalog promotion should have "2.56%" percentage discount
diff --git a/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature
index 7f9da33f13..2dd0589aaf 100644
--- a/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature
+++ b/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature
@@ -8,6 +8,7 @@ Feature: Toggling catalog promotion
Given the store operates on a single channel in "United States"
And the store has a "T-Shirt" configurable product
And this product has "PHP T-Shirt" variant priced at "$20.00"
+ And this product has "PHPers T-Shirt" variant priced at "$25.00"
And there is a catalog promotion "Christmas sale" that reduces price by "30%" and applies on "PHP T-Shirt" variant
And I am logged in as an administrator
diff --git a/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature b/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature
index efb5a228cb..7cb7751da4 100644
--- a/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature
+++ b/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature
@@ -44,7 +44,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that catalog promotion with this code already exists
And there should still be only one catalog promotion with code "sale"
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with invalid type of scope
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -56,7 +56,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that type of scope is invalid
And there should be an empty list of catalog promotions
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with scope with invalid configuration
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -68,7 +68,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that scope configuration is invalid
And there should be an empty list of catalog promotions
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to create a catalog promotion with not configured for variants scope
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -80,7 +80,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that at least 1 variant is required
And there should be an empty list of catalog promotions
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with invalid type of action
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -144,10 +144,10 @@ Feature: Validating a catalog promotion creation
And I add scope that applies on variants "PHP T-Shirt" variant and "Kotlin T-Shirt" variant
And I add fixed discount action without amount configured for the "United States" channel
And I try to add it
- Then I should be notified that the fixed amount should be a number and cannot be empty
+ Then I should be notified that the fixed amount cannot be empty
And there should be an empty list of catalog promotions
- @api
+ @api @ui @mink:chromedriver
Scenario: Trying to create a catalog promotion with wrong value of fixed discount action
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -158,10 +158,10 @@ Feature: Validating a catalog promotion creation
And I add scope that applies on variants "PHP T-Shirt" variant and "Kotlin T-Shirt" variant
And I add invalid fixed discount action with non number in amount for the "United States" channel
And I try to add it
- Then I should be notified that the fixed amount should be a number and cannot be empty
+ Then I should be notified that the fixed amount should be a number
And there should be an empty list of catalog promotions
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with fixed discount action with invalid channel
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -176,7 +176,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that at least one of the provided channel codes does not exist
And there should be an empty list of catalog promotions
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to create a catalog promotion with taxon type without taxons
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -188,7 +188,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that I must add at least one taxon
And there should be an empty list of catalog promotions
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with taxon type with invalid taxons
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -200,7 +200,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that I can add only existing taxon
And there should be an empty list of catalog promotions
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to create a catalog promotion with product type without products
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
@@ -212,7 +212,7 @@ Feature: Validating a catalog promotion creation
Then I should be notified that I must add at least one product
And there should be an empty list of catalog promotions
- @api
+ @api @no-ui
Scenario: Trying to create a catalog promotion with product type with invalid products
When I want to create a new catalog promotion
And I specify its code as "winter_sale"
diff --git a/features/admin/promotion/managing_coupons/adding_coupon.feature b/features/admin/promotion/managing_coupons/adding_coupon.feature
index 5f7c5ece9b..772eb1d6e6 100644
--- a/features/admin/promotion/managing_coupons/adding_coupon.feature
+++ b/features/admin/promotion/managing_coupons/adding_coupon.feature
@@ -10,7 +10,7 @@ Feature: Adding a new coupon
And it is coupon based promotion
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new coupon
When I want to create a new coupon for this promotion
And I specify its code as "SANTA2016"
diff --git a/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature b/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature
index b5a84c2ae0..8232afd110 100644
--- a/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature
+++ b/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature
@@ -14,7 +14,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix
And it is coupon based promotion
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Being unable to generate too many coupons with prefix
Given I have generated 8 coupons for this promotion with code length 1 and prefix "CHRISTMAS_"
When I want to generate new coupons for this promotion
@@ -25,7 +25,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix
Then I should be notified that generating 2 coupons with code length equal to 1 is not possible
And there should still be 8 coupons related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Being unable to generate too many coupons with suffix
Given I have generated 8 coupons for this promotion with code length 1 and suffix "_CHRISTMAS"
When I want to generate new coupons for this promotion
@@ -36,7 +36,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix
Then I should be notified that generating 2 coupons with code length equal to 1 is not possible
And there should still be 8 coupons related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Being unable to generate too many coupons with prefix and suffix
Given I have generated 8 coupons for this promotion with code length 1, prefix "CHRISTMAS_" and suffix "_SALE"
When I want to generate new coupons for this promotion
diff --git a/features/admin/promotion/managing_coupons/browsing_coupons.feature b/features/admin/promotion/managing_coupons/browsing_coupons.feature
index e514a73c6b..8fd48cc773 100644
--- a/features/admin/promotion/managing_coupons/browsing_coupons.feature
+++ b/features/admin/promotion/managing_coupons/browsing_coupons.feature
@@ -9,7 +9,7 @@ Feature: Browsing promotion coupons
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing coupons of a promotion
When I want to view all coupons of this promotion
And there should be 1 coupon related to this promotion
diff --git a/features/admin/promotion/managing_coupons/coupon_generate_validation.feature b/features/admin/promotion/managing_coupons/coupon_generate_validation.feature
index 55c4b06ba1..f36e2758ae 100644
--- a/features/admin/promotion/managing_coupons/coupon_generate_validation.feature
+++ b/features/admin/promotion/managing_coupons/coupon_generate_validation.feature
@@ -10,7 +10,7 @@ Feature: Coupon generate instruction validation
And it is coupon based promotion
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Trying to generate new coupons without specifying their amount
When I want to generate new coupons for this promotion
And I do not specify its amount
@@ -21,7 +21,7 @@ Feature: Coupon generate instruction validation
Then I should be notified that generate amount is required
And there should be 0 coupon related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Trying to generate new coupons without specifying their code length
When I want to generate new coupons for this promotion
And I do not specify their code length
@@ -32,7 +32,7 @@ Feature: Coupon generate instruction validation
Then I should be notified that generate code length is required
And there should be 0 coupon related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Trying to generate new coupons with code length impossible to generate
When I want to generate new coupons for this promotion
And I specify their code length as 50
@@ -43,7 +43,7 @@ Feature: Coupon generate instruction validation
Then I should be notified that generate code length is out of range
And there should be 0 coupon related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Trying to generate new coupons with amount and code length impossible to generate
When I want to generate new coupons for this promotion
And I specify their code length as 1
diff --git a/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature b/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature
index 9331d10ee5..b3215b5736 100644
--- a/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature
+++ b/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature
@@ -9,7 +9,7 @@ Feature: Coupon unique code validation
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Trying to add coupon with taken code
When I want to create a new coupon for this promotion
And I specify its code as "SANTA2016"
diff --git a/features/admin/promotion/managing_coupons/coupon_validation.feature b/features/admin/promotion/managing_coupons/coupon_validation.feature
index cefc1334d1..170bc3cf1f 100644
--- a/features/admin/promotion/managing_coupons/coupon_validation.feature
+++ b/features/admin/promotion/managing_coupons/coupon_validation.feature
@@ -10,7 +10,7 @@ Feature: Coupon validation
And it is coupon based promotion
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new coupon without specifying its code
When I want to create a new coupon for this promotion
And I do not specify its code
@@ -21,7 +21,7 @@ Feature: Coupon validation
Then I should be notified that code is required
And there should be 0 coupons related to this promotion
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new coupon with a too long code
When I want to create a new coupon for this promotion
And I limit its usage to 30 times
@@ -31,7 +31,7 @@ Feature: Coupon validation
And I try to add it
Then I should be notified that code is too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new coupon with usage limit below one
When I want to create a new coupon for this promotion
And I specify its code as "SANTA2016"
@@ -42,7 +42,7 @@ Feature: Coupon validation
Then I should be notified that coupon usage limit must be at least one
And there should be 0 coupons related to this promotion
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new coupon with per customer usage limit below one
When I want to create a new coupon for this promotion
And I specify its code as "SANTA2016"
diff --git a/features/admin/promotion/managing_coupons/deleting_coupon.feature b/features/admin/promotion/managing_coupons/deleting_coupon.feature
index f54dd31f2c..4d675de437 100644
--- a/features/admin/promotion/managing_coupons/deleting_coupon.feature
+++ b/features/admin/promotion/managing_coupons/deleting_coupon.feature
@@ -9,7 +9,7 @@ Feature: Deleting a coupon
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted coupon should disappear from the registry
When I delete "SANTA2016" coupon related to this promotion
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature b/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature
index dee4e09b77..571d71b495 100644
--- a/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature
+++ b/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple coupons
And this promotion has "SANTA1", "SANTA2" and "SANTA3" coupons
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple coupons at once
When I browse coupons of this promotion
And I check the "SANTA1" coupon
diff --git a/features/admin/promotion/managing_coupons/editing_coupon.feature b/features/admin/promotion/managing_coupons/editing_coupon.feature
index c1e4afe187..e498c2c702 100644
--- a/features/admin/promotion/managing_coupons/editing_coupon.feature
+++ b/features/admin/promotion/managing_coupons/editing_coupon.feature
@@ -9,7 +9,7 @@ Feature: Editing promotion coupon
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Changing coupon expires date
When I want to modify the "SANTA2016" coupon for this promotion
And I change its expiration date to "21.05.2019"
@@ -17,7 +17,7 @@ Feature: Editing promotion coupon
Then I should be notified that it has been successfully edited
And this coupon should be valid until "21.05.2019"
- @ui @api
+ @todo @ui @api
Scenario: Changing coupons usage limit
When I want to modify the "SANTA2016" coupon for this promotion
And I change its usage limit to 50
@@ -25,7 +25,7 @@ Feature: Editing promotion coupon
Then I should be notified that it has been successfully edited
And this coupon should have 50 usage limit
- @ui @api
+ @todo @ui @api
Scenario: Changing coupons per customer usage limit
When I want to modify the "SANTA2016" coupon for this promotion
And I change its per customer usage limit to 20
@@ -33,7 +33,7 @@ Feature: Editing promotion coupon
Then I should be notified that it has been successfully edited
And this coupon should have 20 per customer usage limit
- @ui @api
+ @todo @ui @api
Scenario: Changing whether it can be reused from cancelled orders
When I want to modify the "SANTA2016" coupon for this promotion
And I make it not reusable from cancelled orders
@@ -41,7 +41,7 @@ Feature: Editing promotion coupon
Then I should be notified that it has been successfully edited
And this coupon should not be reusable from cancelled orders
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change code of promotion coupon
When I want to modify the "SANTA2016" coupon for this promotion
Then I should not be able to edit its code
diff --git a/features/admin/promotion/managing_coupons/generating_coupon.feature b/features/admin/promotion/managing_coupons/generating_coupon.feature
index 5fa2812afa..dbacc815fc 100644
--- a/features/admin/promotion/managing_coupons/generating_coupon.feature
+++ b/features/admin/promotion/managing_coupons/generating_coupon.feature
@@ -10,7 +10,7 @@ Feature: Generating new coupons
And it is coupon based promotion
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Generating a new coupons
When I want to generate new coupons for this promotion
And I choose the amount of 5 coupons to be generated
@@ -21,7 +21,7 @@ Feature: Generating new coupons
Then I should be notified that they have been successfully generated
And there should be 5 coupons related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Generating new coupons without expiration date
When I want to generate new coupons for this promotion
And I choose the amount of 5 coupons to be generated
@@ -31,7 +31,7 @@ Feature: Generating new coupons
Then I should be notified that they have been successfully generated
And there should be 5 coupons related to this promotion
- @api @ui
+ @api @todo @ui
Scenario: Generating new coupons with a large long code length value
When I want to generate new coupons for this promotion
And I choose the amount of 10 coupons to be generated
diff --git a/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature b/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature
index 1918ed8e36..2e471f496e 100644
--- a/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature
+++ b/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature
@@ -10,7 +10,7 @@ Feature: Generating new coupons with prefix and suffix
And it is coupon based promotion
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Generating new coupons with prefix
When I want to generate new coupons for this promotion
And I choose the amount of 5 coupons to be generated
@@ -21,7 +21,7 @@ Feature: Generating new coupons with prefix and suffix
And there should be 5 coupons related to this promotion
And all of the coupon codes should be prefixed with "CHRISTMAS_"
- @api @ui
+ @api @todo @ui
Scenario: Generating new coupons with suffix
When I want to generate new coupons for this promotion
And I choose the amount of 5 coupons to be generated
@@ -32,7 +32,7 @@ Feature: Generating new coupons with prefix and suffix
And there should be 5 coupons related to this promotion
And all of the coupon codes should be suffixed with "_CHRISTMAS"
- @api @ui
+ @api @todo @ui
Scenario: Generating new coupons with prefix and suffix
When I want to generate new coupons for this promotion
And I choose the amount of 5 coupons to be generated
diff --git a/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature b/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature
index d475ad68a9..3e69e883cf 100644
--- a/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature
+++ b/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature
@@ -15,7 +15,7 @@ Feature: Not being able to delete a coupon which is in use
And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Being unable to delete a used coupon
When I try to delete "SANTA2016" coupon related to this promotion
Then I should be notified that it is in use and cannot be deleted
diff --git a/features/admin/promotion/managing_coupons/sorting_coupons.feature b/features/admin/promotion/managing_coupons/sorting_coupons.feature
index e1eb8ba9d7..fb58cdd941 100644
--- a/features/admin/promotion/managing_coupons/sorting_coupons.feature
+++ b/features/admin/promotion/managing_coupons/sorting_coupons.feature
@@ -19,69 +19,69 @@ Feature: Sorting listed coupons
And this coupon expires on "20-02-2023"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Coupons are sorted by descending number of uses by default
When I want to view all coupons of this promotion
Then I should see 3 coupons on the list
And the first coupon should have code "Y"
- @ui @api
+ @todo @ui @api
Scenario: Changing the number of uses sorting order to ascending
Given I am browsing coupons of this promotion
When I sort coupons by ascending number of uses
Then I should see 3 coupons on the list
And the first coupon should have code "X"
- @ui @api
+ @todo @ui @api
Scenario: Sorting coupons by code in descending order
Given I am browsing coupons of this promotion
When I sort coupons by descending code
Then I should see 3 coupons on the list
And the first coupon should have code "Z"
- @ui @api
+ @todo @ui @api
Scenario: Sorting coupons by code in ascending order
Given I am browsing coupons of this promotion
When I sort coupons by ascending code
Then I should see 3 coupons on the list
And the first coupon should have code "X"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by usage limit in descending order
Given I am browsing coupons of this promotion
When I sort coupons by descending usage limit
Then I should see 3 coupons on the list
And the first coupon should have code "X"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by usage limit in ascending order
Given I am browsing coupons of this promotion
When I sort coupons by ascending usage limit
Then I should see 3 coupons on the list
And the first coupon should have code "Z"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by usage limit per customer in descending order
Given I am browsing coupons of this promotion
When I sort coupons by descending usage limit per customer
Then I should see 3 coupons on the list
And the first coupon should have code "X"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by usage limit per customer in ascending order
Given I am browsing coupons of this promotion
When I sort coupons by ascending usage limit per customer
Then I should see 3 coupons on the list
And the first coupon should have code "Y"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by expiration date in descending order
Given I am browsing coupons of this promotion
When I sort coupons by descending expiration date
Then I should see 3 coupons on the list
And the first coupon should have code "Z"
- @ui @no-postgres @api
+ @todo @ui @no-postgres @api
Scenario: Sorting coupons by expiration date in ascending order
Given I am browsing coupons of this promotion
When I sort coupons by ascending expiration date
diff --git a/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature b/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature
index 64bd6d998f..0ef74c8253 100644
--- a/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature
+++ b/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature
@@ -10,13 +10,13 @@ Feature: Accessing the coupons management from the promotion page
And it is a coupon based promotion
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Being able to manage promotion's coupons
When I modify a "Christmas sale" promotion
And I want to manage this promotion coupons
Then I should be on this promotion's coupons management page
- @ui @no-api
+ @todo @ui @no-api
Scenario: Add new promotion and not being able to manage promotion's coupons
When I create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
diff --git a/features/admin/promotion/managing_promotions/adding_promotion.feature b/features/admin/promotion/managing_promotions/adding_promotion.feature
index 8ca1c91bea..ef27e4019b 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion.feature
@@ -75,3 +75,11 @@ Feature: Adding a new promotion
And I add it
Then I should be notified that it has been successfully created
And the "Full metal promotion" promotion should not applies to discounted items
+
+ @ui @mink:chromedriver @no-api
+ Scenario: Seeing rule and action configuration forms
+ When I want to create a new promotion
+ And I add a new rule
+ And I add a new action
+ Then I should see the rule configuration form
+ And I should see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
index 65ae9d7bc3..12bcaed068 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature
@@ -9,7 +9,7 @@ Feature: Adding promotion in different languages
And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui
Scenario: Adding a promotion with a label in a different language
When I want to create a new promotion
And I specify its code as "FULL_METAL_PROMOTION"
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
index 9aed8f5060..b129b3048d 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature
@@ -8,7 +8,7 @@ Feature: Adding a new promotion with action
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with fixed discount
When I want to create a new promotion
And I specify its code as "10_for_all_products"
@@ -18,7 +18,7 @@ Feature: Adding a new promotion with action
Then I should be notified that it has been successfully created
And the "$10.00 for all products!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with item percentage discount
When I want to create a new promotion
And I specify its code as "promotion_for_all_product_items"
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
index da704d642d..3620dcd099 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature
@@ -17,5 +17,4 @@ Feature: Adding a new promotion with action configured in different channels
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
And it is also configured with amount of "£16.00" for "Web-GB" channel
And I add it
- Then I should be notified that it has been successfully created
- And the "Item fixed discount for all products!" promotion should appear in the registry
+ Then the "Item fixed discount for all products!" promotion should be successfully created
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
index 62e7e2388c..185fd9859d 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature
@@ -16,10 +16,9 @@ Feature: Adding promotion with filter
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
And I specify that on "United States" channel this action should be applied to items with price greater than "$10.00"
And I add it
- Then I should be notified that it has been successfully created
- And the "$10 discount for all products over $10!" promotion should appear in the registry
+ Then the "$10 discount for all products over $10!" promotion should be successfully created
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with item fixed discount only for products between 10 and 100
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -30,31 +29,31 @@ Feature: Adding promotion with filter
Then I should be notified that it has been successfully created
And the "$10 discount for (almost) all products!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with fixed discount for all t-shirts
Given the store classifies its products as "T-Shirts" and "Mugs"
When I want to create a new promotion
And I specify its code as "10_for_all_t_shirts"
And I name it "$10 discount for all T-Shirts!"
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
- And I specify that this action should be applied to items from "T-Shirts" category
+ And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for all T-Shirts!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with fixed discount for PHP T-Shirt
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
And I specify its code as "10_for_php_t_shirt"
And I name it "$10 discount for PHP T-Shirts!"
And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel
- And I specify that this action should be applied to the "PHP T-Shirt" product
+ And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for PHP T-Shirts!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with item percentage discount only for products over 10
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -65,7 +64,7 @@ Feature: Adding promotion with filter
Then I should be notified that it has been successfully created
And the "$10 discount for all products over $10!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with item percentage discount only for products between 10 and 100
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -73,29 +72,29 @@ Feature: Adding promotion with filter
And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel
And I specify that on "United States" channel this action should be applied to items with price between "$10.00" and "$100.00"
And I add it
- Then I should be notified that it has been successfully created
+ Then the "$10 discount for (almost) all products!" promotion should be successfully created
And the "$10 discount for (almost) all products!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with 10% percentage discount for all t-shirts
Given the store classifies its products as "T-Shirts" and "Mugs"
When I want to create a new promotion
And I specify its code as "10_for_all_t_shirts"
And I name it "$10 discount for all T-Shirts!"
And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel
- And I specify that this action should be applied to items from "T-Shirts" category
+ And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "$10 discount for all T-Shirts!" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with 10% percentage discount for PHP T-Shirt
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
And I specify its code as "10_for_php_t_shirt"
And I name it "10% discount for PHP T-Shirts!"
And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel
- And I specify that this action should be applied to the "PHP T-Shirt" product
+ And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel
And I add it
Then I should be notified that it has been successfully created
And the "10% discount for PHP T-Shirts!" promotion should appear in the registry
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
index 8014a1e5f1..1fc72625c0 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature
@@ -9,17 +9,17 @@ Feature: Adding a new promotion with rule
And the store classifies its products as "T-Shirts" and "Mugs"
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with taxon rule
When I want to create a new promotion
And I specify its code as "HOLIDAY_SALE"
And I name it "Holiday sale"
And I add the "Has at least one from taxons" rule configured with "T-Shirts" taxon and "Mugs" taxon
And I add it
- Then I should be notified that it has been successfully created
+ Then the "Holiday sale" promotion should be successfully created
And the "Holiday sale" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with total price of items from taxon rule
When I want to create a new promotion
And I specify its code as "100_MUGS_PROMOTION"
@@ -29,7 +29,7 @@ Feature: Adding a new promotion with rule
Then I should be notified that it has been successfully created
And the "100 Mugs promotion" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new promotion with contains product rule
Given the store has a product "PHP T-Shirt" priced at "$100.00"
When I want to create a new promotion
@@ -40,7 +40,7 @@ Feature: Adding a new promotion with rule
Then I should be notified that it has been successfully created
And the "PHP T-Shirt promotion" promotion should appear in the registry
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a new group based promotion
Given the store has a customer group "Wholesale"
When I want to create a new promotion
@@ -50,11 +50,3 @@ Feature: Adding a new promotion with rule
And I add it
Then I should be notified that it has been successfully created
And the "Wholesale promotion" promotion should appear in the registry
-
- @ui @javascript @no-api
- Scenario: Adding a new promotion of default type with one action
- When I want to create a new promotion
- And I add a new rule
- And I add a new action
- Then I should see the rule configuration form
- And I should see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
index 5c572c6738..35be86e7e1 100644
--- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
+++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature
@@ -10,11 +10,10 @@ Feature: Adding a new promotion with rule configured in different channels
And I am logged in as an administrator
@api @ui @mink:chromedriver
- Scenario: Adding a new promotion with total price of items
+ Scenario: Adding a new promotion with total price of items from taxon rule
When I want to create a new promotion
And I specify its code as "100_IN_EVERY_CURRENCY"
And I name it "100 in every currency"
And I add the "Item total" rule configured with "€100.00" amount for "United States" channel and "£100.00" amount for "Web-GB" channel
And I add it
- Then I should be notified that it has been successfully created
- And the "100 in every currency" promotion should appear in the registry
+ Then the "100 in every currency" promotion should be successfully created
diff --git a/features/admin/promotion/managing_promotions/browsing_promotions.feature b/features/admin/promotion/managing_promotions/browsing_promotions.feature
index 22161f20b5..b4a3b7dcce 100644
--- a/features/admin/promotion/managing_promotions/browsing_promotions.feature
+++ b/features/admin/promotion/managing_promotions/browsing_promotions.feature
@@ -9,13 +9,13 @@ Feature: Browsing promotions
And there is a promotion "Basic promotion"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Browsing promotions
When I want to browse promotions
Then I should see a single promotion in the list
And the "Basic promotion" promotion should exist in the registry
- @api @ui
+ @api @todo @ui
Scenario: Browsing manage button for coupon based promotion
Given the store has promotion "Christmas sale" with coupon "Santa's gift"
When I want to browse promotions
diff --git a/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature b/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature
index b3f907f5ff..63a61df75d 100644
--- a/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature
+++ b/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature
@@ -11,7 +11,7 @@ Feature: Deleting multiple promotions
And there is also a promotion "Easter sale"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple promotions at once
When I browse promotions
And I check the "Christmas sale" promotion
diff --git a/features/admin/promotion/managing_promotions/editing_promotion.feature b/features/admin/promotion/managing_promotions/editing_promotion.feature
index 2eabd044bd..749665eb86 100644
--- a/features/admin/promotion/managing_promotions/editing_promotion.feature
+++ b/features/admin/promotion/managing_promotions/editing_promotion.feature
@@ -62,7 +62,7 @@ Feature: Editing promotion
Then I should be able to modify a "Christmas sale" promotion
@ui @no-api
- Scenario: Remove priority from existing promotion
+ Scenario: Removing priority from existing promotion
When I want to modify a "Christmas sale" promotion
And I remove its priority
And I save my changes
@@ -76,3 +76,13 @@ Feature: Editing promotion
And I save my changes
Then I should be notified that it has been successfully edited
And the "Christmas sale" promotion should have priority 1
+
+ @ui @mink:chromedriver
+ Scenario: Removing rule and action from existing promotion
+ Given the promotion gives "$10.00" discount to every order with quantity at least 1
+ When I want to modify a "Holiday sale" promotion
+ And I remove its last rule
+ And I remove its last action
+ And I save my changes
+ Then I should not see the rule configuration form
+ And I should not see the action configuration form
diff --git a/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature b/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature
index 7b8eb87ea4..61325a8c1e 100644
--- a/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature
+++ b/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature
@@ -11,7 +11,7 @@ Feature: Filtering promotions by coupon code
And the store has promotion "Christmas sale" with coupon "MAGIC"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Filtering promotions by coupon code
When I want to browse promotions
And I filter promotions by coupon code equal "MAGIC"
diff --git a/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature b/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature
index 7454f04ec8..76ca873d81 100644
--- a/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature
+++ b/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature
@@ -9,7 +9,7 @@ Feature: Preventing from removing products that are used in promotion rules
And the store has "Mug" and "Cup" products
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Being prevented from removing a product that is in use by a promotion rule
Given there is a promotion "Christmas sale" with "Contains product" rule with product "Mug"
When I try to delete the "Mug" product
diff --git a/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature b/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature
index 842506bcfb..4032b439ba 100644
--- a/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature
+++ b/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature
@@ -9,7 +9,7 @@ Feature: Preventing from removing taxons that are used in promotion rules
And the store has "Mugs" taxonomy
And I am logged in as an administrator
- @api @ui @mink:chromedriver
+ @api @todo @ui @mink:chromedriver
Scenario: Being prevented from removing taxon that is in use by a promotion rule
Given there is a promotion "Christmas sale" with "Total price of items from taxon" rule configured with "Mugs" taxon and $100 amount for "United States" channel
When I try to delete taxon named "Mugs"
diff --git a/features/admin/promotion/managing_promotions/promotion_validation.feature b/features/admin/promotion/managing_promotions/promotion_validation.feature
index 3ffb1944aa..5e66860c10 100644
--- a/features/admin/promotion/managing_promotions/promotion_validation.feature
+++ b/features/admin/promotion/managing_promotions/promotion_validation.feature
@@ -69,7 +69,7 @@ Feature: Promotion validation
And I try to save my changes
Then I should be notified that promotion cannot end before it starts
- @api @ui @mink:chromedriver
+ @api @ui
Scenario: Adding a promotion with label exceeding 255 characters
Given there is a promotion "Christmas sale"
When I want to modify this promotion
@@ -77,7 +77,7 @@ Feature: Promotion validation
And I try to save my changes
Then I should be notified that promotion label in "Polish (Poland)" locale is too long
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to add a new promotion without specifying a order percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -87,7 +87,7 @@ Feature: Promotion validation
Then I should be notified that this value should not be blank
And promotion with name "Christmas sale" should not be added
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to add a new promotion without specifying an item percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -97,7 +97,7 @@ Feature: Promotion validation
Then I should be notified that this value should not be blank
And promotion with name "Christmas sale" should not be added
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to add a new promotion with a wrong order percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
@@ -107,7 +107,7 @@ Feature: Promotion validation
Then I should be notified that a percentage discount value must be between 0% and 100%
And promotion with name "Christmas sale" should not be added
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Trying to add a new promotion with a wrong item percentage discount
When I want to create a new promotion
And I specify its code as "christmas_sale"
diff --git a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
index 6fe1bd3044..0fecb83828 100644
--- a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
+++ b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature
@@ -8,7 +8,7 @@ Feature: Promotion filters validation
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with wrong minimum price on price range filter
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
@@ -19,7 +19,7 @@ Feature: Promotion filters validation
Then I should be notified that a minimum value should be a numeric value
And promotion with name "$10 discount for all products over $10!" should not be added
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Adding a promotion with wrong maximum price on price range filter
When I want to create a new promotion
And I specify its code as "10_for_all_products_over_10"
diff --git a/features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature b/features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
similarity index 100%
rename from features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
rename to features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature
diff --git a/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature b/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature
index 9cb2b9be00..c81c925823 100644
--- a/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature
+++ b/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature
@@ -11,7 +11,7 @@ Feature: Seeing errors in promotion channel based configuration
And there is a promotion "Holiday promotion"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing the number of errors per channel in order fixed discount
Given this promotion gives "$10.00" discount to every order in the "Web" channel and "$5.00" discount to every order in the "Mobile" channel
When I want to modify a "Holiday promotion" promotion
@@ -19,7 +19,7 @@ Feature: Seeing errors in promotion channel based configuration
And I try to save my changes
And I should see that the action for "Mobile" channel has 1 validation error
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing the number of errors per channel in product fixed discount
Given this promotion gives "$2.00" off on every product in the "Web" channel and "$3.00" off in the "Mobile" channel
When I want to modify a "Holiday promotion" promotion
@@ -27,7 +27,7 @@ Feature: Seeing errors in promotion channel based configuration
And I try to save my changes
And I should see that the action for "Mobile" channel has 1 validation error
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing the number of errors per channel in product percentage discount
Given this promotion gives "5%" off on every product in the "Web" channel and "10%" off in the "Mobile" channel
When I want to modify a "Holiday promotion" promotion
@@ -35,7 +35,7 @@ Feature: Seeing errors in promotion channel based configuration
And I try to save my changes
And I should see that the action for "Mobile" channel has 1 validation error
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing the number of errors per channel with rule based on items' total
Given this promotion gives "$10.00" discount to every order in the "Web" channel and "$5.00" discount to every order in the "Mobile" channel
And this promotion only applies to orders with a total of at least "$100.00" for "Web" channel and "$50.00" for "Mobile" channel
diff --git a/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature b/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature
index cd44a2e403..bdf1a06f33 100644
--- a/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature
+++ b/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature
@@ -11,21 +11,21 @@ Feature: Sorting listed promotions by priority
And there is a promotion "Pugs For Everyone" with priority 0
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Promotions are sorted by priority in descending order by default
When I want to browse promotions
Then I should see 3 promotions on the list
And the first promotion on the list should have name "Honour Harambe"
And the last promotion on the list should have name "Pugs For Everyone"
- @api @ui
+ @api @todo @ui
Scenario: Promotion's default priority is 0 which puts it at the bottom of the list
Given there is a promotion "Flying Pigs"
When I want to browse promotions
Then I should see 4 promotions on the list
And the last promotion on the list should have name "Flying Pigs"
- @api @ui
+ @api @todo @ui
Scenario: Promotion added with priority -1 is set at the top of the list
Given there is a promotion "Flying Pigs" with priority -1
When I want to browse promotions
diff --git a/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature b/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature
index fd49bd1d71..200d22eb25 100644
--- a/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature
+++ b/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature
@@ -13,7 +13,7 @@ Feature: Removing a catalog promotions
And there is a catalog promotion "Winter Sale" that reduces price by "30%" and applies on "Clothes" taxon
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Removing an expired catalog promotion
Given it is "2022-08-22" now
And the catalog promotion "Winter Sale" operates between "2021-12-20" and "2021-12-30"
@@ -22,14 +22,14 @@ Feature: Removing a catalog promotions
And there should be an empty list of catalog promotions
And "PHP T-Shirt" variant should not be discounted
- @api @ui
+ @api @todo @ui
Scenario: Removing an active catalog promotion without any time limits
When I request the removal of "Winter Sale" catalog promotion
Then I should be notified that the removal operation has started successfully
And there should be an empty list of catalog promotions
And "PHP T-Shirt" variant should not be discounted
- @api @ui
+ @api @todo @ui
Scenario: Removing an active catalog promotion in the time range
Given it is "2022-12-15" now
And the catalog promotion "Winter Sale" operates between "2022-12-01" and "2022-12-30"
@@ -38,7 +38,7 @@ Feature: Removing a catalog promotions
And there should be an empty list of catalog promotions
And "PHP T-Shirt" variant should not be discounted
- @api @ui
+ @api @todo @ui
Scenario: Removing a scheduled catalog promotion
Given it is "2022-08-22" now
And the catalog promotion "Winter Sale" operates between "2022-12-01" and "2023-02-28"
diff --git a/features/admin/promotion/tracking_usage/checking_promotion_usage.feature b/features/admin/promotion/tracking_usage/checking_promotion_usage.feature
index 3cfae047d5..65f8c0c115 100644
--- a/features/admin/promotion/tracking_usage/checking_promotion_usage.feature
+++ b/features/admin/promotion/tracking_usage/checking_promotion_usage.feature
@@ -16,7 +16,7 @@ Feature: Checking a promotion usage after placing an order
And there is a promotion "Christmas promotion"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing item fixed discount promotion usage unchanged after order placement
Given the promotion gives "$10.00" off on every product with minimum price at "$50.00"
And the promotion gives another "$5.00" off on every product classified as "T-Shirts"
@@ -26,7 +26,7 @@ Feature: Checking a promotion usage after placing an order
When I browse promotions
Then the promotion "Christmas promotion" should not be used
- @api @ui
+ @api @todo @ui
Scenario: Seeing item fixed discount promotion usage increased after order placement
Given the promotion gives "$10.00" off on every product with minimum price at "$50.00"
And the promotion gives another "$5.00" off on every product classified as "Mugs"
@@ -36,7 +36,7 @@ Feature: Checking a promotion usage after placing an order
When I browse promotions
Then the promotion "Christmas promotion" should be used 1 time
- @api @ui
+ @api @todo @ui
Scenario: Seeing shipping percentage discount promotion usage unchanged after order placement
Given the promotion gives "100%" discount on shipping to every order
And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
diff --git a/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature b/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature
index e20c381ff9..13f33e97f9 100644
--- a/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature
+++ b/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature
@@ -12,7 +12,7 @@ Feature: Decreasing a promotion coupon usage after cancelling an order
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion coupon usage decreased after order cancellation
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon
@@ -21,7 +21,7 @@ Feature: Decreasing a promotion coupon usage after cancelling an order
When I browse all coupons of "Christmas sale" promotion
Then "SANTA2016" coupon should be used 0 times
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion coupon usage decreased to 1 after second order cancellation
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon
diff --git a/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature b/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature
index 5b739c684c..784e5f2878 100644
--- a/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature
+++ b/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature
@@ -12,7 +12,7 @@ Feature: Decreasing a promotion usage after cancelling an order
And there is a promotion "Limited promotion" limited to 5 usages
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion usage decreased after order cancellation
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt"
diff --git a/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature b/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature
index bea00a7c3f..74c1fe682c 100644
--- a/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature
+++ b/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature
@@ -12,7 +12,7 @@ Feature: Increasing a promotion coupon usage after placing an order
And the store has promotion "Christmas sale" with coupon "SANTA2016"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion coupon usage increased after order placement
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon
@@ -20,7 +20,7 @@ Feature: Increasing a promotion coupon usage after placing an order
When I browse all coupons of "Christmas sale" promotion
Then "SANTA2016" coupon should be used 1 time
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion coupon usage increased correctly after few orders placement
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon
diff --git a/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature b/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature
index 412a1c5e74..d77fe5d378 100644
--- a/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature
+++ b/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature
@@ -13,7 +13,7 @@ Feature: Increasing a promotion usage after placing an order
And it gives "$10.00" discount to every order
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Seeing promotion usage increased after order placement
Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
And the customer bought a single "PHP T-Shirt"
diff --git a/features/admin/redirecting_on_login_after_being_logout.feature b/features/admin/redirecting_on_login_after_being_logout.feature
index f370b73f79..baa80ac119 100644
--- a/features/admin/redirecting_on_login_after_being_logout.feature
+++ b/features/admin/redirecting_on_login_after_being_logout.feature
@@ -8,7 +8,7 @@ Feature: Redirecting on login page
Given the store operates on a single channel in "United States"
And I have been logged out from administration
- @ui @no-api
+ @todo @ui @no-api
Scenario: Redirecting on login page after being logout
When I try to open administration dashboard
Then I should be on login page
diff --git a/features/admin/resetting_password.feature b/features/admin/resetting_password.feature
index d92e04bad8..b20a5c5dfd 100644
--- a/features/admin/resetting_password.feature
+++ b/features/admin/resetting_password.feature
@@ -8,7 +8,7 @@ Feature: Resetting an administrator's password
Given the store operates on a single channel in "United States"
And there is an administrator "sylius@example.com" identified by "sylius"
- @email @api @ui
+ @email @api @todo @ui
Scenario: Sending an administrator's password reset request
When I want to reset password
And I specify email as "sylius@example.com"
@@ -16,7 +16,7 @@ Feature: Resetting an administrator's password
Then I should be notified that email with reset instruction has been sent
And an email with instructions on how to reset the administrator's password should be sent to "sylius@example.com"
- @email @api @ui
+ @email @api @todo @ui
Scenario: Notifying about sending reset instructions even when an admin with email does not exist
When I want to reset password
And I specify email as "does-not-exist@example.com"
@@ -24,7 +24,7 @@ Feature: Resetting an administrator's password
Then I should be notified that email with reset instruction has been sent
But "does-not-exist@example.com" should receive no emails
- @ui @api
+ @todo @ui @api
Scenario: Changing my administrator's password
Given I have already received a resetting password email
When I follow the instructions to reset my password
@@ -34,7 +34,7 @@ Feature: Resetting an administrator's password
Then I should be notified that my password has been successfully changed
And I should be able to log in as "sylius@example.com" authenticated by "newp@ssw0rd" password
- @ui @api
+ @todo @ui @api
Scenario: Trying to change my administrator's password twice without sending a new password reset request
Given I have already received an administrator's password resetting email
When I follow the instructions to reset my password
@@ -53,7 +53,7 @@ Feature: Resetting an administrator's password
And I reset it
Then I should be notified that the password reset token has expired
- @ui @no-api
+ @todo @ui @no-api
Scenario: Trying to change my administrator's password using an expired reset token
Given I have already received an administrator's password resetting email
But my password reset token has already expired
diff --git a/features/admin/resetting_password_validation.feature b/features/admin/resetting_password_validation.feature
index 244d1944fe..9ed42a66f6 100644
--- a/features/admin/resetting_password_validation.feature
+++ b/features/admin/resetting_password_validation.feature
@@ -7,14 +7,14 @@ Feature: Resetting an administrator's password validation
Background:
Given there is an administrator "sylius@example.com" identified by "sylius"
- @ui @api
+ @todo @ui @api
Scenario: Trying to reset my administrator's password without specifying email
When I want to reset password
And I do not specify an email
And I try to reset it
Then I should be notified that the email is required
- @ui @api
+ @todo @ui @api
Scenario: Trying to reset my administrator's password with an empty value
Given I have already received an administrator's password resetting email
When I follow the instructions to reset my password
@@ -23,14 +23,14 @@ Feature: Resetting an administrator's password validation
And I try to reset it
Then I should be notified that the new password is required
- @ui @api
+ @todo @ui @api
Scenario: Trying to reset my administrator's password with an invalid email
When I want to reset password
And I specify email as "sylius@examplecom"
And I try to reset it
Then I should be notified that the email is not valid
- @ui @api
+ @todo @ui @api
Scenario: Trying to reset my administrator's password with a wrong confirmation password
Given I have already received an administrator's password resetting email
When I follow the instructions to reset my password
@@ -39,7 +39,7 @@ Feature: Resetting an administrator's password validation
And I try to reset it
Then I should be notified that the entered passwords do not match
- @ui @api
+ @todo @ui @api
Scenario: Trying to reset my administrator's password with a too short password
Given I have already received an administrator's password resetting email
When I follow the instructions to reset my password
diff --git a/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature b/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature
index a97ac4017f..2c9c676149 100644
--- a/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature
+++ b/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature
@@ -8,7 +8,7 @@ Feature: Securing access to the administration panel after using the back button
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Securing access to administration dashboard after using the back button after logging out
When I am on the administration dashboard
And I log out
diff --git a/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature b/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature
index 1e3067a39a..2f4ee99e11 100644
--- a/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature
+++ b/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature
@@ -15,7 +15,7 @@ Feature: Accessing shipment's order from the shipments index
And the customer chose "UPS" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Accessing shipment's order from the shipment
When I browse shipments
And I move to the details of first shipment's order
diff --git a/features/admin/shipping/managing_shipments/browsing_shipments.feature b/features/admin/shipping/managing_shipments/browsing_shipments.feature
index 2e92aeb6b5..bd4f57f2f1 100644
--- a/features/admin/shipping/managing_shipments/browsing_shipments.feature
+++ b/features/admin/shipping/managing_shipments/browsing_shipments.feature
@@ -21,20 +21,20 @@ Feature: Browsing shipments
And the customer chose "UPS" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing shipments and their states in one channel
When I browse shipments
Then I should see 2 shipments in the list
And I should see the shipment of order "#00000001" as "Shipped"
And I should see the shipment of order "#00000002" as "Ready"
- @ui @api
+ @todo @ui @api
Scenario: Shipments are sorted by newest as default
When I browse shipments
Then I should see shipment for the "#00000002" order as 1st in the list
And I should see shipment for the "#00000001" order as 2nd in the list
- @ui @api
+ @todo @ui @api
Scenario: Not seeing shipments in cart state
Given the customer "customer@example.com" added "Banana" product to the cart
When I browse shipments
diff --git a/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature b/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
index 91fe974e5f..a606678cc9 100644
--- a/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
+++ b/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
@@ -27,7 +27,7 @@ Feature: Browsing shipments from multiple channels
And the customer chose "FEDEX" shipping method with "Bank transfer" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing shipments and their states from multiple channels
When I browse shipments
And I should see 2 shipments in the list
diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature
index 6c54dabca5..b50e56d276 100644
--- a/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature
+++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature
@@ -27,7 +27,7 @@ Feature: Filtering shipments by a channel
And the customer chose "FEDEX" shipping method with "Bank transfer" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering shipments by channel on index
When I browse shipments
And I choose "United States" as a channel filter
diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature
index 1f19221e6b..37e233ca4f 100644
--- a/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature
+++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature
@@ -21,7 +21,7 @@ Feature: Filtering shipments by a shipping method
And the customer chose "DHL" shipping method to "United States" with "Offline" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering shipments by a shipping method
When I browse shipments
And I choose "DHL" as a shipping method filter
diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature
index cf0433040d..342a93f29b 100644
--- a/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature
+++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature
@@ -20,7 +20,7 @@ Feature: Filtering shipments by state
And the customer chose "UPS" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Filtering payments in state "Shipped"
When I browse shipments
And I choose "shipped" as a shipment state
diff --git a/features/admin/shipping/managing_shipments/seeing_shipment_details.feature b/features/admin/shipping/managing_shipments/seeing_shipment_details.feature
index 705dba90bc..969ab3abb9 100644
--- a/features/admin/shipping/managing_shipments/seeing_shipment_details.feature
+++ b/features/admin/shipping/managing_shipments/seeing_shipment_details.feature
@@ -16,7 +16,7 @@ Feature: Seeing basic information about shipment
And the customer chose "UPS" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Seeing basic information about shipment
When I view the first shipment of the order "#00000001"
Then I should see 2 "Apple" units in the list
diff --git a/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature b/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature
index 25f9a56f28..b60ecad13f 100644
--- a/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature
+++ b/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature
@@ -38,7 +38,7 @@ Feature: Shipping a shipment from shipment list
Then I should see the shipment of order "#00000001" as "Shipped"
And I should see the shipment of order "#00000001" shipped at "20-02-2020 10:30:05"
- @api
+ @api @no-ui
Scenario: Shipping a shipment that has been already shipped
Given this order has already been shipped
When I try to ship the shipment of order "#00000001"
diff --git a/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature
index cae33de4e5..24409c183d 100644
--- a/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature
+++ b/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature
@@ -8,7 +8,7 @@ Feature: Adding a new shipping category
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new shipping category with detailed information
When I want to create a new shipping category
And I specify its code as "OVER_SIZED"
diff --git a/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature b/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature
index 6bfbd96de6..38eb1b29a0 100644
--- a/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature
+++ b/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature
@@ -9,7 +9,7 @@ Feature: Browsing shipping categories
And the store has "Over sized" and "Standard" shipping category
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing defined shipping categories
When I browse shipping categories
Then I should see 2 shipping categories in the list
diff --git a/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature b/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature
index e4e8dddeec..0a9521d87b 100644
--- a/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature
+++ b/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature
@@ -9,7 +9,7 @@ Feature: Deleting multiple shipping categories
And the store has "Big" and "Small" shipping category
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple shipping categories at once
When I browse shipping categories
And I check the "Big" shipping category
diff --git a/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature
index 4c65065dd2..c8492c60ae 100644
--- a/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature
+++ b/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature
@@ -9,7 +9,7 @@ Feature: Deleting a shipping category
And the store has "Standard" shipping category
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted shipping category should disappear from the registry
When I delete shipping category "Standard"
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature
index c888921c5e..7c75a3997b 100644
--- a/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature
+++ b/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature
@@ -9,12 +9,12 @@ Feature: Editing shipping method
And the store has "Standard" shipping category
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Seeing disabled code field when editing shipping category
When I modify a shipping category "Standard"
Then I should not be able to edit its code
- @ui @api
+ @todo @ui @api
Scenario: Renaming the shipping category
When I want to modify a shipping category "Standard"
And I rename it to "Normal"
diff --git a/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature b/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature
index cbaccc74b1..aa22cc1993 100644
--- a/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature
+++ b/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature
@@ -9,7 +9,7 @@ Feature: Shipping category unique code validation
And the store has "Standard" shipping category identified by "STANDARD"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add shipping category with taken code
When I want to create a new shipping category
And I specify its code as "STANDARD"
diff --git a/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature b/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature
index 290bc70458..3c78452750 100644
--- a/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature
+++ b/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature
@@ -8,7 +8,7 @@ Feature: Shipping category validation
Given the store operates on a single channel in "United States"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new shipping category without specifying its code
When I want to create a new shipping category
And I name it "Standard"
@@ -17,7 +17,7 @@ Feature: Shipping category validation
Then I should be notified that code is required
And shipping category with name "Standard" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new shipping category with a too long code
When I want to create a new shipping category
And I name it "Standard"
@@ -25,7 +25,7 @@ Feature: Shipping category validation
And I try to add it
Then I should be notified that code is too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new shipping category without specifying its name
When I want to create a new shipping category
And I specify its code as "STANDARD"
diff --git a/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature
index 90eadb63ce..3b99c1a7b1 100644
--- a/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature
+++ b/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature
@@ -20,8 +20,7 @@ Feature: Adding a new shipping method
And I choose "Flat rate per shipment" calculator
And I specify its amount as 50 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
@ui @mink:chromedriver @api
Scenario: Adding a new shipping method with description and flat rate per shipment
@@ -33,10 +32,9 @@ Feature: Adding a new shipping method
And I choose "Flat rate per shipment" calculator
And I specify its amount as 50 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a new shipping method with flat rate per unit
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
@@ -45,10 +43,9 @@ Feature: Adding a new shipping method
And I choose "Flat rate per unit" calculator
And I specify its amount as 20 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding a new shipping method for channel
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
@@ -59,8 +56,7 @@ Feature: Adding a new shipping method
And I choose "Flat rate per unit" calculator
And I specify its amount as 20 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
And the shipping method "FedEx Carrier" should be available in channel "Web-US"
@ui @mink:chromedriver @api
@@ -74,5 +70,4 @@ Feature: Adding a new shipping method
And I specify its amount as 50 for "Web-US" channel
And I specify its amount as 40 for "Web-GB" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
diff --git a/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature b/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature
index 3e6206533b..106eb980e3 100644
--- a/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature
+++ b/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature
@@ -21,8 +21,7 @@ Feature: Adding a new shipping method with rule
And I specify its amount as 50 for "Web-US" channel
And I add the "Total weight greater than or equal" rule configured with "20"
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
@ui @mink:chromedriver @api
Scenario: Adding a new shipping method with total weight less than or equal rule
@@ -35,8 +34,7 @@ Feature: Adding a new shipping method with rule
And I specify its amount as 50 for "Web-US" channel
And I add the "Total weight less than or equal" rule configured with "20"
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
@ui @mink:chromedriver @api
Scenario: Adding a new shipping method with order total greater than or equal rule
@@ -49,8 +47,7 @@ Feature: Adding a new shipping method with rule
And I specify its amount as 50 for "Web-US" channel
And I add the "Items total greater than or equal" rule configured with $200 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
@ui @mink:chromedriver @api
Scenario: Adding a new shipping method with order total less than or equal rule
@@ -63,5 +60,4 @@ Feature: Adding a new shipping method with rule
And I specify its amount as 50 for "Web-US" channel
And I add the "Items total less than or equal" rule configured with $200 for "Web-US" channel
And I add it
- Then I should be notified that it has been successfully created
- And the shipping method "FedEx Carrier" should appear in the registry
+ Then the "FedEx Carrier" shipping method should be successfully created
diff --git a/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature b/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature
index fa633c8062..4d641f64e9 100644
--- a/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature
+++ b/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature
@@ -9,20 +9,20 @@ Feature: Archiving obsolete shipping methods
And the store allows shipping with "UPS Carrier" and "FedEx Carrier"
And I am logged in as an administrator
- @ui @api
+ @ui @mink:chromedriver @api
Scenario: Archiving a shipping method
Given I am browsing shipping methods
When I archive the "UPS Carrier" shipping method
Then the only shipping method on the list should be "FedEx Carrier"
- @ui @api
+ @ui @mink:chromedriver @api
Scenario: Seeing only archived shipping methods
Given the shipping method "UPS Carrier" is archival
And I am browsing shipping methods
When I filter archival shipping methods
Then the only shipping method on the list should be "UPS Carrier"
- @ui @api
+ @ui @mink:chromedriver @api
Scenario: Restoring an archival shipping method
Given the shipping method "UPS Carrier" is archival
And I am browsing archival shipping methods
diff --git a/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature b/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature
index 2aa41a15dc..982c22b908 100644
--- a/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature
+++ b/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature
@@ -9,7 +9,7 @@ Feature: Deleting multiple shipping methods
And the store allows shipping with "UPS", "FedEx" and "DHL"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple shipping methods at once
When I browse shipping methods
And I check the "UPS" shipping method
diff --git a/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature
index cb5f0d412d..36332fa307 100644
--- a/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature
+++ b/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature
@@ -9,8 +9,9 @@ Feature: Deleting a shipping method
And the store allows shipping with "UPS Ground"
And I am logged in as an administrator
- @ui @api
+ @ui @mink:chromedriver @api
Scenario: Deleted shipping method should disappear from the registry
- When I delete shipping method "UPS Ground"
+ When I browse shipping methods
+ And I delete shipping method "UPS Ground"
Then I should be notified that it has been successfully deleted
- Then this shipping method should no longer exist in the registry
+ And this shipping method should no longer exist in the registry
diff --git a/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature b/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature
index e432189829..2eb60a5303 100644
--- a/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature
+++ b/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature
@@ -10,41 +10,41 @@ Feature: Denying access to shipping methods for unauthorized users
And the store has a zone "United States" with code "US"
And the store allows shipping with "UPS Carrier" identified by "UPS_CARRIER"
- @api
+ @api @no-ui
Scenario: Trying to add a new shipping method as a unauthorized user
When I try to create a new shipping method with valid data
And I try to add it
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to rename the shipping method
Given I try to modify a shipping method "UPS Carrier"
When I rename it to "UPS Transport" in "English (United States)"
And I try to save my changes
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to browse shipping methods
When I try to browse shipping methods
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to show shipping method
When I try to show "UPS Carrier" shipping method
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to archive a shipping method
When I try to archive the "UPS Carrier" shipping method
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to restore a shipping method
Given the shipping method "UPS Carrier" is archival
When I try to restore the "UPS Carrier" shipping method
Then I should be notified that my access has been denied
- @api
+ @api @no-ui
Scenario: Trying to delete shipping method
When I try to delete shipping method "UPS Carrier"
Then I should be notified that my access has been denied
diff --git a/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature
index afbbb00dd9..89b7b78693 100644
--- a/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature
+++ b/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature
@@ -14,7 +14,7 @@ Feature: Prevent deletion of used shipping method
And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui @api
+ @ui @mink:chromedriver @api
Scenario: Being unable to delete a shipping method which is in use
When I try to delete shipping method "DHL Express"
Then I should be notified that it is in use
diff --git a/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature b/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature
index ea4aef4c1f..5d0b70c13f 100644
--- a/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature
+++ b/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature
@@ -11,7 +11,7 @@ Feature: Seeing errors in shipping method charges
And the store has a zone "United States" with code "US"
And I am logged in as an administrator
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Seeing the number of errors with per shipment charges
Given the store has "FedEx Carrier" shipping method with "$20.00" fee per shipment for "Web" channel and "$15.00" for "Mobile" channel
When I want to modify this shipping method
@@ -19,7 +19,7 @@ Feature: Seeing errors in shipping method charges
And I try to save my changes
Then I should see that the shipping charges for "Mobile" channel has 1 validation error
- @ui @no-api
+ @ui @mink:chromedriver @no-api
Scenario: Seeing the number of errors with per unit charges
Given the store has "FedEx Carrier" shipping method with "$20.00" fee per unit for "Web" channel and "$15.00" for "Mobile" channel
When I want to modify this shipping method
diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature
index ac638f5396..7f3d93cf4a 100644
--- a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature
+++ b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature
@@ -10,7 +10,7 @@ Feature: Shipping method flat rate per shipment calculator validation
And the store has a zone "United States" with code "US"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Trying to add a new shipping method with flat rate per shipment calculator without specifying its amount
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
@@ -21,7 +21,7 @@ Feature: Shipping method flat rate per shipment calculator validation
Then I should be notified that amount for "Web" channel should not be blank
And shipping method with name "FedEx Carrier" should not be added
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Trying to add a new shipping method with flat rate per shipment calculator with charge below 0
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature
index b5afb7ffa6..623d87b44b 100644
--- a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature
+++ b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature
@@ -10,7 +10,7 @@ Feature: Shipping method flat rate per unit calculator validation
And the store has a zone "United States" with code "US"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Trying to add a new shipping method with flat rate per unit calculator without specifying its amount
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
@@ -21,7 +21,7 @@ Feature: Shipping method flat rate per unit calculator validation
Then I should be notified that amount for "Web" channel should not be blank
And shipping method with name "FedEx Carrier" should not be added
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Trying to add a new shipping method with flat rate per unit calculator with charge below 0
When I want to create a new shipping method
And I specify its code as "FED_EX_CARRIER"
diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature
index 43ef82d7cb..50c9e7eb41 100644
--- a/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature
+++ b/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature
@@ -11,7 +11,7 @@ Feature: Shipping method unique code validation
And the store allows shipping with "UPS Ground" identified by "UPS"
And I am logged in as an administrator
- @ui @api @javascript
+ @ui @api @mink:chromedriver
Scenario: Trying to add shipping method with taken code
When I want to create a new shipping method
And I specify its code as "UPS"
diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature
index 742161eb54..76b3b71192 100644
--- a/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature
+++ b/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature
@@ -10,7 +10,6 @@ Feature: Shipping method validation
And the store is available in "English (United States)"
And I am logged in as an administrator
-
@no-ui @api
Scenario: Trying to add shipping method translation in unexisting locale
When I want to create a new shipping method
diff --git a/features/admin/signing_in_to_administration_panel.feature b/features/admin/signing_in_to_administration_panel.feature
index 734035d780..cfe1914cba 100644
--- a/features/admin/signing_in_to_administration_panel.feature
+++ b/features/admin/signing_in_to_administration_panel.feature
@@ -9,7 +9,7 @@ Feature: Signing in to the administration panel
And there is a user "ted@example.com" identified by "bear"
And there is an administrator "admin@example.com" identified by "sylius"
- @ui @api
+ @todo @ui @api
Scenario: Sign in with email and password
When I want to log in
And I specify the username as "admin@example.com"
@@ -17,7 +17,7 @@ Feature: Signing in to the administration panel
And I log in
Then I should be logged in
- @ui @api
+ @todo @ui @api
Scenario: Sign in with bad credentials
When I want to log in
And I specify the username as "admin@example.com"
@@ -26,7 +26,7 @@ Feature: Signing in to the administration panel
Then I should be notified about bad credentials
And I should not be logged in
- @ui @api
+ @todo @ui @api
Scenario: Sign in using customer account
When I want to log in
And I specify the username as "ted@example.com"
diff --git a/features/admin/statistics.feature b/features/admin/statistics.feature
index 71100eb2ac..cb46c4ec04 100644
--- a/features/admin/statistics.feature
+++ b/features/admin/statistics.feature
@@ -12,7 +12,7 @@ Feature: Statistics
And this product has "Red XL" variant priced at "$40.00"
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing statistics for the current year and default channel when expectations are not specified
Given it is "last day of December last year" now
And 2 new customers have fulfilled 2 orders placed for total of "$1,000.00"
@@ -26,7 +26,7 @@ Feature: Statistics
And there should be total sales of "$7,000.58"
And the average order value should be "$1,166.76"
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Seeing statistics for the previous year
Given it is "first day of January last year" now
And 3 new customers have fulfilled 2 orders placed for total of "$2,000.00"
@@ -39,7 +39,7 @@ Feature: Statistics
And there should be total sales of "$2,000.00"
And the average order value should be "$1,000.00"
- @ui @javascript @no-api
+ @ui @todo @javascript @no-api
Scenario: Seeing statistics for the next year
Given it is "first day of January last year" now
And 3 new customers have fulfilled 2 orders placed for total of "$2,000.00"
@@ -53,7 +53,7 @@ Feature: Statistics
And there should be total sales of "$10,000.74"
And the average order value should be "$1,428.68"
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Seeing statistics that include only fulfilled orders that were not cancelled
Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00"
And 2 more new customers have placed 2 orders for total of "$459.00"
diff --git a/features/admin/statistics_per_channel.feature b/features/admin/statistics_per_channel.feature
index 6544f3ccdd..e8ac73b000 100644
--- a/features/admin/statistics_per_channel.feature
+++ b/features/admin/statistics_per_channel.feature
@@ -13,7 +13,7 @@ Feature: Statistics for a specific channel
And the store allows paying Offline
And I am logged in as an administrator
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing basic statistics for the first channel by default
Given 3 new customers have fulfilled 4 orders placed for total of "$8,566.00" mostly "Onion" product
And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product
@@ -23,7 +23,7 @@ Feature: Statistics for a specific channel
And there should be total sales of "$8,566.00"
And the average order value should be "$2,141.50"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Switching to the channel with only fulfilled orders
Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00" mostly "Onion" product
And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product
@@ -35,7 +35,7 @@ Feature: Statistics for a specific channel
And there should be total sales of "$459.00"
And the average order value should be "$229.50"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Switching to the channel with both fulfilled and placed orders
Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00" mostly "Onion" product
And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product
@@ -47,14 +47,14 @@ Feature: Statistics for a specific channel
And there should be total sales of "$5,241.00"
And the average order value should be "$1,310.25"
- @no-api @ui
+ @todo @no-api @ui
Scenario: Seeing recent orders in a specific channel
Given 3 new customers have placed 4 orders for total of "$8,566.00" mostly "Onion" product
And 2 more new customers have placed 2 orders for total of "$459.00" mostly "Banana" product
When I view statistics for "WEB-POLAND" channel
Then I should see 4 new orders in the list
- @no-api @ui
+ @todo @no-api @ui
Scenario: Seeing recent orders in a specific channel
Given 3 new customers have placed 4 orders for total of "$8,566.00" mostly "Onion" product
And 2 more new customers have placed 2 orders for total of "$459.00" mostly "Banana" product
diff --git a/features/admin/switching_admins_locale.feature b/features/admin/switching_admins_locale.feature
index 8aae78290d..24fc884313 100644
--- a/features/admin/switching_admins_locale.feature
+++ b/features/admin/switching_admins_locale.feature
@@ -11,33 +11,33 @@ Feature: Switching locales on admin's panel
And I am logged in as an administrator
And I am using "English (United States)" locale for my panel
- @ui
+ @todo @ui
Scenario: Changing my preferred locale
Given I am editing my details
When I set my locale to "Spanish (Mexico)"
Then I should be viewing the administration panel in "Spanish (Mexico)"
- @ui
+ @todo @ui
Scenario: Changing my preferred language to a locale that does not exist in the store
Given the locale "French (France)" does not exist in the store
And I am editing my details
When I set my locale to "French (France)"
Then I should be viewing the administration panel in "French (France)"
- @ui
+ @todo @ui
Scenario: Changing panel's locale doesn't change shop's locale
Given I am editing my details
When I set my locale to "Spanish (Mexico)"
And I browse that channel
Then I should still shop using the "English (United States)" locale
- @ui
+ @todo @ui
Scenario: Changing shop's locale has doesn't affect admin panel's locale
Given I switched the shop's locale to "Spanish (Mexico)"
When I open administration dashboard
Then I should still be viewing the administration panel in "English (United States)"
- @ui
+ @todo @ui
Scenario: Locales are saved per each admin's preference
Given I am using "Spanish (Mexico)" locale for my panel
And there is an administrator "admin@example.com" identified by "sylius"
diff --git a/features/admin/taxation/managing_tax_categories/adding_tax_category.feature b/features/admin/taxation/managing_tax_categories/adding_tax_category.feature
index 023c2af286..51201fe72a 100644
--- a/features/admin/taxation/managing_tax_categories/adding_tax_category.feature
+++ b/features/admin/taxation/managing_tax_categories/adding_tax_category.feature
@@ -7,7 +7,7 @@ Feature: Adding a new tax category
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new tax category
When I want to create a new tax category
And I specify its code as "food_and_beverage"
@@ -16,7 +16,7 @@ Feature: Adding a new tax category
Then I should be notified that it has been successfully created
And the tax category "Food and Beverage" should appear in the registry
- @ui @api
+ @todo @ui @api
Scenario: Adding a new tax category with a description
When I want to create a new tax category
And I specify its code as "food_and_beverage"
diff --git a/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature b/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature
index c1b6d5c71e..0a3ba694b1 100644
--- a/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature
+++ b/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature
@@ -8,7 +8,7 @@ Feature: Deleting multiple tax categories
Given the store has tax categories "Alcohol", "Food" and "Books"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple tax categories at once
When I browse tax categories
And I check the "Alcohol" tax category
diff --git a/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature b/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature
index 5758a072df..74ff518fad 100644
--- a/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature
+++ b/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature
@@ -8,7 +8,7 @@ Feature: Deleting a tax category
Given the store has a tax category "Alcohol" with a code "alcohol"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleted tax category should disappear from the registry
When I delete tax category "Alcohol"
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/taxation/managing_tax_categories/editing_tax_category.feature b/features/admin/taxation/managing_tax_categories/editing_tax_category.feature
index fa33d446b2..be7783824f 100644
--- a/features/admin/taxation/managing_tax_categories/editing_tax_category.feature
+++ b/features/admin/taxation/managing_tax_categories/editing_tax_category.feature
@@ -8,12 +8,12 @@ Feature: Editing tax category
Given the store has a tax category "Alcohol" with a code "alcohol"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Inability of changing the code of an existing tax category
When I want to modify a tax category "Alcohol"
Then I should not be able to edit its code
- @ui @api
+ @todo @ui @api
Scenario: Renaming the tax category
When I want to modify a tax category "Alcohol"
And I rename it to "Food & Alcohol"
diff --git a/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature b/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature
index 295ba8483a..6537ef5066 100644
--- a/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature
+++ b/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature
@@ -8,7 +8,7 @@ Feature: Tax category unique code validation
Given the store has a tax category "Alcohol" with a code "alcohol"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add tax category with taken code
When I want to create a new tax category
And I name it "Food and Beverage"
diff --git a/features/admin/taxation/managing_tax_categories/tax_category_validation.feature b/features/admin/taxation/managing_tax_categories/tax_category_validation.feature
index 73724b627e..347c4b766b 100644
--- a/features/admin/taxation/managing_tax_categories/tax_category_validation.feature
+++ b/features/admin/taxation/managing_tax_categories/tax_category_validation.feature
@@ -7,7 +7,7 @@ Feature: Tax category validation
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new tax category without specifying its code
When I want to create a new tax category
And I name it "Food and Beverage"
@@ -16,7 +16,7 @@ Feature: Tax category validation
Then I should be notified that code is required
And tax category with name "Food and Beverage" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new tax category with a too long code
When I want to create a new tax category
And I name it "Food and Beverage"
@@ -24,7 +24,7 @@ Feature: Tax category validation
And I try to add it
Then I should be notified that code is too long
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new tax category without specifying its name
When I want to create a new tax category
And I specify its code as "food_and_beverage"
@@ -33,7 +33,7 @@ Feature: Tax category validation
Then I should be notified that name is required
And tax category with code "food_and_beverage" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove name from existing tax category
Given the store has a tax category "Alcoholic Drinks" with a code "alcohol"
When I want to modify this tax category
diff --git a/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature b/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature
index 85cc677755..ea08816fdd 100644
--- a/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature
+++ b/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature
@@ -77,7 +77,7 @@ Feature: Adding a new tax rate
Then I should be notified that it has been successfully created
And the tax rate "United States Sales Tax" should appear in the registry
- @api @ui @mink:chromedriver
+ @api @ui
Scenario: Adding a new tax rate which will be included in product price
When I want to create a new tax rate
And I specify its code as "US_SALES_TAX"
diff --git a/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature b/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature
index 8cc35ebfe1..0f503ebd0c 100644
--- a/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature
+++ b/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature
@@ -11,7 +11,7 @@ Feature: Deleting multiple tax rates
And the store has "High VAT" tax rate of 40% for "Food" for the rest of the world
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple tax rates at once
When I browse tax rates
And I check the "Low VAT" tax rate
diff --git a/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature b/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature
index 6408428459..7cddd29ef5 100644
--- a/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature
@@ -35,7 +35,7 @@ Feature: Adding images to an existing taxon
And this taxon should have an image with "banner" type
And it should also have an image with "thumbnail" type
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Adding multiple images of the same type to an existing taxon
When I want to modify the "T-Shirts" taxon
And I attach the "t-shirts.jpg" image with "banner" type to this taxon
diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon.feature b/features/admin/taxonomy/managing_taxons/adding_taxon.feature
index 8c13291ac8..c2014adff5 100644
--- a/features/admin/taxonomy/managing_taxons/adding_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/adding_taxon.feature
@@ -8,7 +8,7 @@ Feature: Adding a new taxon
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new taxon
When I want to create a new taxon
And I specify its code as "t-shirts"
@@ -18,7 +18,7 @@ Feature: Adding a new taxon
Then I should be notified that it has been successfully created
And the "T-Shirts" taxon should appear in the registry
- @ui @api
+ @todo @ui @api
Scenario: Adding a new taxon with slug and description
When I want to create a new taxon
And I specify its code as "category"
diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature
index 6f968b64f5..2ad49f8310 100644
--- a/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature
+++ b/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature
@@ -9,7 +9,7 @@ Feature: Adding a new taxon for parent
And the store has "Category" taxonomy
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new taxon for specific parent taxon
When I want to create a new taxon for "Category"
And I specify its code as "guns"
diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature
index 231859d48d..419393f0c9 100644
--- a/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature
+++ b/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature
@@ -13,6 +13,7 @@ Feature: Adding a new taxon with images
When I want to create a new taxon
And I specify its code as "t-shirts"
And I name it "T-Shirts" in "English (United States)"
+ And I set its slug to "t-shirts"
And I attach the "t-shirts.jpg" image with "banner" type
And I add it
Then I should be notified that it has been successfully created
@@ -24,6 +25,7 @@ Feature: Adding a new taxon with images
When I want to create a new taxon
And I specify its code as "t-shirts"
And I name it "T-Shirts" in "English (United States)"
+ And I set its slug to "t-shirts"
And I attach the "t-shirts.jpg" image with "banner" type
And I attach the "t-shirts.jpg" image with "thumbnail" type
And I add it
diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature
index 6785abf8fc..e92aaecc91 100644
--- a/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature
+++ b/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature
@@ -9,7 +9,7 @@ Feature: Adding a new taxon with parent specified
And the store has "Category" taxonomy
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Adding a new taxon with parent
When I want to create a new taxon
And I set its parent taxon to "Category"
diff --git a/features/admin/taxonomy/managing_taxons/browsing_taxon.feature b/features/admin/taxonomy/managing_taxons/browsing_taxon.feature
index 203531ea23..ed00c83a69 100644
--- a/features/admin/taxonomy/managing_taxons/browsing_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/browsing_taxon.feature
@@ -8,7 +8,7 @@ Feature: Browsing taxons
Given the store classifies its products as "T-Shirts" and "Accessories"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing taxons in store
When I want to see all taxons in store
Then I should see 2 taxons on the list
diff --git a/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature b/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature
index 21820c9c3f..9c1ee01279 100644
--- a/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature
@@ -18,7 +18,7 @@ Feature: Changing images of an existing taxon
Then I should be notified that it has been successfully edited
And this taxon should have an image with "banner" type
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Changing the type of image of a taxon
Given the "T-Shirts" taxon has an image "ford.jpg" with "thumbnail" type
And the "T-Shirts" taxon also has an image "t-shirts.jpg" with "banner" type
diff --git a/features/admin/taxonomy/managing_taxons/deleting_taxon.feature b/features/admin/taxonomy/managing_taxons/deleting_taxon.feature
index 749b08ab21..34157dfcd7 100644
--- a/features/admin/taxonomy/managing_taxons/deleting_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/deleting_taxon.feature
@@ -8,13 +8,13 @@ Feature: Deleting a taxon
Given I am logged in as an administrator
And the store operates on a channel named "Web Store"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Deleted taxon should disappear from the registry
Given the store classifies its products as "T-Shirts"
When I delete taxon named "T-Shirts"
Then the taxon named "T-Shirts" should no longer exist in the registry
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Deleting a taxon with a child does not delete any other taxons
Given the store classifies its products as "Main catalog"
And the "Main catalog" taxon has children taxon "Shoes" and "Shovels"
@@ -25,14 +25,14 @@ Feature: Deleting a taxon
And the taxon named "Women" should no longer exist in the registry
But the "Shovels" taxon should appear in the registry
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Being unable to delete a menu taxon of a channel
Given the store classifies its products as "T-Shirts" and "Caps"
And channel "Web Store" has menu taxon "Caps"
When I try to delete taxon named "Caps"
Then I should be notified that I cannot delete a menu taxon of any channel
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Deleting a taxon that is a main taxon of a product
Given the store classifies its products as "T-Shirts"
And the store has a product "T-Shirts PHP"
@@ -41,7 +41,7 @@ Feature: Deleting a taxon
Then the taxon named "T-Shirts" should no longer exist in the registry
And the product "T-Shirts PHP" should no longer have a main taxon
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Deleting root taxon above menu taxon
Given the store has "Main Category" taxonomy
And the store has "Clothes Category" taxonomy
diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon.feature b/features/admin/taxonomy/managing_taxons/editing_taxon.feature
index eeec5248a6..2c2f5395f6 100644
--- a/features/admin/taxonomy/managing_taxons/editing_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/editing_taxon.feature
@@ -9,7 +9,7 @@ Feature: Editing a taxon
And the store classifies its products as "T-Shirts" and "Accessories"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Renaming a taxon
When I want to modify the "T-Shirts" taxon
And I rename it to "Stickers" in "English (United States)"
@@ -17,7 +17,7 @@ Feature: Editing a taxon
Then I should be notified that it has been successfully edited
And this taxon name should be "Stickers"
- @ui @api
+ @todo @ui @api
Scenario: Changing description
When I want to modify the "T-Shirts" taxon
And I change its description to "Main taxonomy for stickers" in "English (United States)"
@@ -25,7 +25,7 @@ Feature: Editing a taxon
Then I should be notified that it has been successfully edited
And this taxon description should be "Main taxonomy for stickers"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Changing parent taxon
When I want to modify the "T-Shirts" taxon
And I change its parent taxon to "Accessories"
@@ -33,7 +33,7 @@ Feature: Editing a taxon
Then I should be notified that it has been successfully edited
And this taxon should belongs to "Accessories"
- @ui @api
+ @todo @ui @api
Scenario: Being unable to change code of taxon
When I want to modify the "T-Shirts" taxon
Then I should not be able to edit its code
diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature b/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature
index 950cb0789d..94c7cadc27 100644
--- a/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature
+++ b/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature
@@ -8,7 +8,7 @@ Feature: Editing taxon's slug
Given the store is available in "English (United States)"
And I am logged in as an administrator
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Creating a root taxon with an autogenerated slug
When I want to create a new taxon
And I specify its code as "MEDIEVAL_WEAPONS"
@@ -16,7 +16,7 @@ Feature: Editing taxon's slug
And I add it
Then this taxon slug should be "medieval-weapons"
- @ui @api
+ @todo @ui @api
Scenario: Creating a root taxon with a custom slug
When I want to create a new taxon
And I specify its code as "MEDIEVAL_WEAPONS"
@@ -25,7 +25,7 @@ Feature: Editing taxon's slug
And I add it
Then this taxon slug should be "mw"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Creating a child taxon with an autogenerated slug
Given the store has "Medieval weapons" taxonomy
When I want to create a new taxon for "Medieval weapons"
@@ -34,7 +34,7 @@ Feature: Editing taxon's slug
And I add it
Then this taxon slug should be "medieval-weapons/siege-engines"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Creating a child taxon with autogenerated slug by setting the parent
Given the store has "Medieval weapons" taxonomy
When I want to create a new taxon
@@ -44,7 +44,7 @@ Feature: Editing taxon's slug
And I add it
Then this taxon slug should be "medieval-weapons/pikes"
- @ui @api
+ @todo @ui @api
Scenario: Creating a child taxon with a custom slug
Given the store has "Medieval weapons" taxonomy
When I want to create a new taxon for "Medieval weapons"
@@ -54,13 +54,13 @@ Feature: Editing taxon's slug
And I add it
Then this taxon slug should be "medieval-weapons/siege"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled slug field when editing a taxon
Given the store has "Medieval weapons" taxonomy
When I want to modify the "Medieval weapons" taxon
Then the slug field should not be editable
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Prevent from editing the slug while changing a taxon name
Given the store has "Medieval weapons" taxonomy
When I want to modify the "Medieval weapons" taxon
@@ -68,7 +68,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Renaissance weapons" taxon should still be "medieval-weapons"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Prevent from editing the slug while setting the taxon's parent
Given the store has "Medieval weapons" taxonomy
And the store has "Pikes" taxonomy
@@ -77,7 +77,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Pikes" taxon should still be "pikes"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Prevent from editing the slug while changing the taxon's parent
Given the store has "Medieval weapons" taxonomy
Given the store has "Renaissance weapons" taxonomy
@@ -87,7 +87,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Pikes" taxon should still be "medieval-weapons/pikes"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Automatically changing a root taxon's slug while editing a taxon's name
Given the store has "Medieval weapons" taxonomy
When I want to modify the "Medieval weapons" taxon
@@ -96,7 +96,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Renaissance weapons" taxon should be "renaissance-weapons"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Automatically changing a child taxon's slug while editing a taxon's name
Given the store has "Medieval weapons" taxonomy
And the "Medieval weapons" taxon has child taxon "Pikes"
@@ -106,7 +106,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Javelins" taxon should be "medieval-weapons/javelins"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Manually changing a root taxon's slug while editing a taxon's name
Given the store has "Medieval weapons" taxonomy
When I want to modify the "Medieval weapons" taxon
@@ -116,7 +116,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Renaissance weapons" taxon should be "renaissance"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Automatically changing a child taxon's slug when changing the parent
Given the store has "Renaissance weapons" taxonomy
And the store has "Medieval weapons" taxonomy
@@ -127,7 +127,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Pikes" taxon should be "renaissance-weapons/pikes"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Manually changing a child taxon's slug when changing the parent
Given the store has "Renaissance weapons" taxonomy
And the store has "Medieval weapons" taxonomy
@@ -139,7 +139,7 @@ Feature: Editing taxon's slug
And I save my changes
Then the slug of the "Pikes" taxon should be "pikes"
- @ui @javascript @api
+ @todo @ui @javascript @api
Scenario: Manually changing a child taxon's slug while editing a taxon's name
Given the store has "Medieval weapons" taxonomy
And the "Medieval weapons" taxon has child taxon "Pikes"
diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature b/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature
index f65880cd0f..22a9cd8aba 100644
--- a/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature
+++ b/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature
@@ -9,7 +9,7 @@ Feature: Editing taxon's slug in multiple locales
And the store is also available in "Polish (Poland)"
And I am logged in as an administrator
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Creating a root taxon with an autogenerated slug
When I want to create a new taxon
And I specify its code as "MEDIEVAL_WEAPONS"
@@ -19,7 +19,7 @@ Feature: Editing taxon's slug in multiple locales
Then this taxon should have slug "medieval-weapons" in "English (United States)"
And this taxon should have slug "bronie-sredniowieczne" in "Polish (Poland)"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Creating a child taxon with an autogenerated slug
Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale
When I want to create a new taxon for "Medieval weapons"
@@ -30,7 +30,7 @@ Feature: Editing taxon's slug in multiple locales
Then this taxon should have slug "medieval-weapons/siege-engines" in "English (United States)"
And this taxon should have slug "bronie-sredniowieczne/machiny-obleznicze" in "Polish (Poland)"
- @ui @api
+ @todo @ui @api
Scenario: Creating a root taxon with a custom slug
When I want to create a new taxon
And I specify its code as "MEDIEVAL_WEAPONS"
@@ -42,14 +42,14 @@ Feature: Editing taxon's slug in multiple locales
Then this taxon should have slug "mw" in "English (United States)"
And this taxon should have slug "bs" in "Polish (Poland)"
- @ui @no-api
+ @todo @ui @no-api
Scenario: Seeing disabled slug field when editing a taxon
Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale
When I want to modify the "Medieval weapons" taxon
Then the slug field should not be editable in "English (United States)"
Then the slug field should also not be editable in "Polish (Poland)"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Prevent from editing a slug while changing a taxon name
Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale
When I want to modify the "Medieval weapons" taxon
@@ -59,7 +59,7 @@ Feature: Editing taxon's slug in multiple locales
Then this taxon should have slug "medieval-weapons" in "English (United States)"
Then this taxon should have slug "bronie-sredniowieczne" in "Polish (Poland)"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Automatically changing a taxon's slug while editing a taxon's name
Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale
When I want to modify the "Medieval weapons" taxon
@@ -71,7 +71,7 @@ Feature: Editing taxon's slug in multiple locales
Then this taxon should have slug "renaissance-weapons" in "English (United States)"
Then this taxon should have slug "bronie-renesansowe" in "Polish (Poland)"
- @ui @mink:chromedriver @api
+ @todo @ui @mink:chromedriver @api
Scenario: Manually changing a taxon's slug while editing a taxon's name
Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale
When I want to modify the "Medieval weapons" taxon
diff --git a/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature b/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature
index 72f507aad8..71dc0bcb28 100644
--- a/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature
@@ -10,7 +10,7 @@ Feature: Preventing a potential XSS attack while adding a new taxon
And the store has "" taxonomy
And I am logged in as an administrator
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Preventing a potential XSS attack while adding new taxon
When I want to create a new taxon
Then I should be able to change its parent taxon to "Category"
diff --git a/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature b/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature
index d1c4a3f595..6f9ff24f66 100644
--- a/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature
@@ -9,7 +9,7 @@ Feature: Removing images of an existing taxon
And the store classifies its products as "T-Shirts"
And I am logged in as an administrator
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing a single image of a taxon
Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type
When I want to modify the "T-Shirts" taxon
@@ -18,7 +18,7 @@ Feature: Removing images of an existing taxon
Then I should be notified that the changes have been successfully applied
And this taxon should not have any images
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing all images of a taxon
Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type
And the "T-Shirts" taxon also has an image "t-shirts.jpg" with "thumbnail" type
@@ -40,7 +40,7 @@ Feature: Removing images of an existing taxon
And this taxon should have an image with "thumbnail" type
But this taxon should not have any images with "banner" type
- @ui @javascript @api
+ @ui @mink:chromedriver @api
Scenario: Removing only one image of a taxon when all images have same type
Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type
And the "T-Shirts" taxon also has an image "mugs.jpg" with "banner" type
diff --git a/features/admin/taxonomy/managing_taxons/reordering_taxon.feature b/features/admin/taxonomy/managing_taxons/reordering_taxon.feature
index a41db069d3..327c6a85d5 100644
--- a/features/admin/taxonomy/managing_taxons/reordering_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/reordering_taxon.feature
@@ -8,7 +8,7 @@ Feature: Reordering taxons
Given the store classifies its products as "T-Shirts", "Watches", "Belts" and "Wallets"
And I am logged in as an administrator
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Moving up the taxon on list
When I want to see all taxons in store
And I move up "Watches" taxon
@@ -16,7 +16,7 @@ Feature: Reordering taxons
And I should see the taxon named "T-Shirts" in the list
But the first taxon on the list should be "Watches"
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Moving down the taxon on list
When I want to see all taxons in store
And I move down "T-Shirts" taxon
@@ -24,21 +24,21 @@ Feature: Reordering taxons
And I should see the taxon named "Watches" in the list
But the first taxon on the list should be "Watches"
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Moving up the first taxon on list
When I want to see all taxons in store
And I move up "T-Shirts" taxon
Then I should see 4 taxons on the list
And the first taxon on the list should be "T-Shirts"
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Moving down the last taxon on list
When I want to see all taxons in store
And I move down "Wallets" taxon
Then I should see 4 taxons on the list
And the last taxon on the list should be "Wallets"
- @ui @javascript @no-api @todo
+ @todo @ui @javascript @no-api @todo
Scenario: Changing order of the taxon on list
When I want to see all taxons in store
And I move down "T-Shirts" taxon
diff --git a/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature b/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature
index fb71180ba9..92d665076b 100644
--- a/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature
+++ b/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature
@@ -9,7 +9,7 @@ Feature: Taxon unique code validation
And the store classifies its products as "T-Shirts"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add taxon with taken code
When I want to create a new taxon
And I specify its code as "t_shirts"
diff --git a/features/admin/taxonomy/managing_taxons/taxon_validation.feature b/features/admin/taxonomy/managing_taxons/taxon_validation.feature
index 051a53bae0..4cc246d772 100644
--- a/features/admin/taxonomy/managing_taxons/taxon_validation.feature
+++ b/features/admin/taxonomy/managing_taxons/taxon_validation.feature
@@ -16,7 +16,7 @@ Feature: Taxon validation
And I save my changes
Then I should be notified that the locale is not available
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a taxon without specifying its code
When I want to create a new taxon
And I do not specify its code
@@ -25,7 +25,7 @@ Feature: Taxon validation
Then I should be notified that code is required
And taxon named "T-Shirts" should not be added
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a taxon without specifying its name
When I want to create a new taxon
And I specify its code as "t-shirts"
@@ -33,7 +33,7 @@ Feature: Taxon validation
And I try to add it
Then I should be notified that name is required
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a taxon with a too long code
When I want to create a new taxon
And I name it "T-Shirts" in "English (United States)"
@@ -41,7 +41,7 @@ Feature: Taxon validation
And I try to add it
Then I should be notified that code is too long
- @ui @no-api
+ @todo @ui @no-api
Scenario: Trying to add a taxon without specifying its slug
When I want to create a new taxon
And I specify its code as "t-shirts"
@@ -50,7 +50,7 @@ Feature: Taxon validation
And I try to add it
Then I should be notified that slug is required
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a taxon with non unique slug
Given the store classifies its products as "T-Shirts"
When I want to create a new taxon
diff --git a/features/admin/taxonomy/managing_taxons/toggling_taxon.feature b/features/admin/taxonomy/managing_taxons/toggling_taxon.feature
index 2bdfa780ce..0458018e27 100644
--- a/features/admin/taxonomy/managing_taxons/toggling_taxon.feature
+++ b/features/admin/taxonomy/managing_taxons/toggling_taxon.feature
@@ -9,7 +9,7 @@ Feature: Toggling the taxon
And the store classifies its products as "T-Shirts" and "Accessories"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a disabled taxon
When I want to create a new taxon
And I specify its code as "jeans"
@@ -21,7 +21,7 @@ Feature: Toggling the taxon
And the "Jeans" taxon should appear in the registry
And it should be disabled
- @ui @api
+ @todo @ui @api
Scenario: Enabling a Taxon
Given the "T-Shirts" taxon is disabled
When I want to modify the "T-Shirts" taxon
@@ -30,7 +30,7 @@ Feature: Toggling the taxon
Then I should be notified that it has been successfully edited
And it should be enabled
- @ui @api
+ @todo @ui @api
Scenario: Disabling a Taxon
Given the "T-Shirts" taxon is enabled
When I want to modify the "T-Shirts" taxon
diff --git a/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature b/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature
deleted file mode 100644
index 977585b9ea..0000000000
--- a/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature
+++ /dev/null
@@ -1,26 +0,0 @@
-@managing_administrators
-Feature: Administrator unique email and name validation
- In order to uniquely identify administrators
- As an Administrator
- I want to be prevented from adding two administrators with the same email or name
-
- Background:
- Given I am logged in as an administrator
-
- @ui @api
- Scenario: Trying to add a new administrator with taken email
- Given there is an administrator "ted@example.com"
- When I want to create a new administrator
- And I specify its email as "ted@example.com"
- And I try to add it
- Then I should be notified that email must be unique
- And there should still be only one administrator with an email "ted@example.com"
-
- @ui @api
- Scenario: Trying to add a new administrator with taken name
- Given there is an administrator with name "Ted"
- When I want to create a new administrator
- And I specify its name as "Ted"
- And I try to add it
- Then I should be notified that name must be unique
- And there should still be only one administrator with name "Ted"
diff --git a/features/admin/user/managing_administrators/administrator_validation.feature b/features/admin/user/managing_administrators/administrator_validation.feature
index fea2b51831..f524b7a6b8 100644
--- a/features/admin/user/managing_administrators/administrator_validation.feature
+++ b/features/admin/user/managing_administrators/administrator_validation.feature
@@ -30,6 +30,24 @@ Feature: Administrator validation
And I try to add it
Then I should be notified that this email is not valid
+ @ui @api
+ Scenario: Trying to add a new administrator with taken email
+ Given there is an administrator "ted@example.com"
+ When I want to create a new administrator
+ And I specify its email as "ted@example.com"
+ And I try to add it
+ Then I should be notified that email must be unique
+ And there should still be only one administrator with an email "ted@example.com"
+
+ @ui @api
+ Scenario: Trying to add a new administrator with taken name
+ Given there is an administrator with name "Ted"
+ When I want to create a new administrator
+ And I specify its name as "Ted"
+ And I try to add it
+ Then I should be notified that name must be unique
+ And there should still be only one administrator with name "Ted"
+
@ui @api
Scenario: Trying to add a new administrator with too long username specified
When I want to create a new administrator
diff --git a/features/admin/user/managing_administrators/deleting_multiple_administrators.feature b/features/admin/user/managing_administrators/deleting_multiple_administrators.feature
index 16c2661b6f..a9f0feeb24 100644
--- a/features/admin/user/managing_administrators/deleting_multiple_administrators.feature
+++ b/features/admin/user/managing_administrators/deleting_multiple_administrators.feature
@@ -10,7 +10,7 @@ Feature: Deleting multiple administrators
And there is also an administrator "watermelon@example.com"
And I am logged in as "watermelon@example.com" administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple administrators at once
Given I browse administrators
And I check the "banana@example.com" administrator
diff --git a/features/admin/user/managing_customer_groups/adding_customer_group.feature b/features/admin/user/managing_customer_groups/adding_customer_group.feature
index db3b32bd85..b57e3e67a6 100644
--- a/features/admin/user/managing_customer_groups/adding_customer_group.feature
+++ b/features/admin/user/managing_customer_groups/adding_customer_group.feature
@@ -7,7 +7,7 @@ Feature: Adding a new customer group
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Adding a new customer group
When I want to create a new customer group
And I specify its code as "RETAIL"
diff --git a/features/admin/user/managing_customer_groups/browsing_customer_groups.feature b/features/admin/user/managing_customer_groups/browsing_customer_groups.feature
index 78d76a43be..0e03c1d14a 100644
--- a/features/admin/user/managing_customer_groups/browsing_customer_groups.feature
+++ b/features/admin/user/managing_customer_groups/browsing_customer_groups.feature
@@ -9,7 +9,7 @@ Feature: Browsing customer groups
And the store has a customer group "Wholesale"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Browsing customer groups in the store
When I want to browse customer groups
Then I should see 2 customer groups in the list
diff --git a/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature b/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature
index d3708fc73d..ef88457d4a 100644
--- a/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature
+++ b/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature
@@ -8,7 +8,7 @@ Feature: Customer group unique code validation
Given the store has a customer group "Retail" with "RETAIL" code
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new customer group with used code
When I want to create a new customer group
And I specify its code as "RETAIL"
diff --git a/features/admin/user/managing_customer_groups/customer_group_validation.feature b/features/admin/user/managing_customer_groups/customer_group_validation.feature
index 6e4a460cad..b3d6ca4b6e 100644
--- a/features/admin/user/managing_customer_groups/customer_group_validation.feature
+++ b/features/admin/user/managing_customer_groups/customer_group_validation.feature
@@ -7,14 +7,14 @@ Feature: Customer group validation
Background:
Given I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Trying to add a new customer group without a name
When I want to create a new customer group
And I try to add it
Then I should be notified that name is required
And I should be informed that this form contains errors
- @ui @api
+ @todo @ui @api
Scenario: Trying to remove name from an existing customer group
Given the store has a customer group "Retail"
When I want to edit this customer group
diff --git a/features/admin/user/managing_customer_groups/deleting_customer_group.feature b/features/admin/user/managing_customer_groups/deleting_customer_group.feature
index 5e7e60bbce..3a3f81e503 100644
--- a/features/admin/user/managing_customer_groups/deleting_customer_group.feature
+++ b/features/admin/user/managing_customer_groups/deleting_customer_group.feature
@@ -8,7 +8,7 @@ Feature: Deleting customer groups
Given the store has a customer group "Retail"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Deleting a customer group
When I delete the "Retail" customer group
Then I should be notified that it has been successfully deleted
diff --git a/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature b/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature
index c4b23d1a1d..b71a44cd79 100644
--- a/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature
+++ b/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature
@@ -8,7 +8,7 @@ Feature: Deleting multiple customer groups
Given the store has customer groups "Retail", "Wholesale" and "General"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Deleting multiple customer groups at once
When I browse customer groups
And I check the "Retail" customer group
diff --git a/features/admin/user/managing_customer_groups/editing_customer_group.feature b/features/admin/user/managing_customer_groups/editing_customer_group.feature
index 2889afd97c..5c28d88a5a 100644
--- a/features/admin/user/managing_customer_groups/editing_customer_group.feature
+++ b/features/admin/user/managing_customer_groups/editing_customer_group.feature
@@ -8,7 +8,7 @@ Feature: Editing a customer group
Given the store has a customer group "Retail"
And I am logged in as an administrator
- @ui @api
+ @todo @ui @api
Scenario: Changing name of an existing customer group
When I want to edit this customer group
And I specify its name as "Wholesale"
@@ -16,7 +16,7 @@ Feature: Editing a customer group
Then I should be notified that it has been successfully edited
And this customer group with name "Wholesale" should appear in the store
- @ui @api
+ @todo @ui @api
Scenario: Seeing disabled code field while editing customer group
When I want to edit this customer group
Then I should not be able to edit its code
diff --git a/features/admin/user/managing_customers/adding_customer.feature b/features/admin/user/managing_customers/adding_customer.feature
index 0029390f2b..62906b7ab8 100644
--- a/features/admin/user/managing_customers/adding_customer.feature
+++ b/features/admin/user/managing_customers/adding_customer.feature
@@ -8,7 +8,7 @@ Feature: Adding a new customer
Given the store has a customer group "Retail"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Adding a new customer
When I want to create a new customer
And I specify their email as "l.skywalker@gmail.com"
@@ -16,7 +16,7 @@ Feature: Adding a new customer
Then I should be notified that it has been successfully created
And the customer "l.skywalker@gmail.com" should appear in the store
- @api @ui
+ @api @todo @ui
Scenario: Adding a new customer with full details
When I want to create a new customer
And I specify their first name as "Luke"
diff --git a/features/admin/user/managing_customers/adding_customer_account.feature b/features/admin/user/managing_customers/adding_customer_account.feature
index cab1ba145b..38d1e1f5e9 100644
--- a/features/admin/user/managing_customers/adding_customer_account.feature
+++ b/features/admin/user/managing_customers/adding_customer_account.feature
@@ -7,7 +7,7 @@ Feature: Adding a new customer account
Background:
Given I am logged in as an administrator
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Adding a new customer with an account
When I want to create a new customer account
And I specify their email as "l.skywalker@gmail.com"
@@ -18,7 +18,7 @@ Feature: Adding a new customer account
And the customer "l.skywalker@gmail.com" should appear in the store
And the customer "l.skywalker@gmail.com" should have an account created
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Creating an account for existing customer
Given the store has customer "Frodo Baggins" with email "f.baggins@example.com"
When I want to edit this customer
diff --git a/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature b/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature
index 2aea8c7994..f0a35533a8 100644
--- a/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature
+++ b/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature
@@ -7,7 +7,7 @@ Feature: Adding a new customer account after failed creation action
Background:
Given I am logged in as an administrator
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Trying to add new customer with an account without required information
When I want to create a new customer account
And I choose create account option
@@ -19,7 +19,7 @@ Feature: Adding a new customer account after failed creation action
And I should be notified that email is required
And I should be notified that password is required
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Trying to add new customer with an account without email
When I want to create a new customer account
And I choose create account option
@@ -31,7 +31,7 @@ Feature: Adding a new customer account after failed creation action
And I should not be able to select create account option
And I should be notified that email is required
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Trying to add new customer without an account without email
When I want to create a new customer account
And I do not choose create account option
@@ -42,7 +42,7 @@ Feature: Adding a new customer account after failed creation action
And I should be able to select create account option
And I should be notified that email is required
- @api @ui @javascript
+ @api @todo @ui @javascript
Scenario: Trying to add new customer with an account without required information
When I want to create a new customer account
And I choose create account option
diff --git a/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature b/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature
index 5897ab42d0..730d14acfc 100644
--- a/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature
+++ b/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature
@@ -7,7 +7,7 @@ Feature: Create account option availability
Background:
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Being able to create an account for created customer
When I want to create a new customer
And I do not choose create account option
@@ -17,7 +17,7 @@ Feature: Create account option availability
And I should not be able to specify their password
And I should be able to select create account option
- @ui @javascript @no-api
+ @todo @ui @javascript @no-api
Scenario: Not seeing create account option after adding customer with account
When I want to create a new customer account
And I choose create account option
diff --git a/features/admin/user/managing_customers/changing_customer_email.feature b/features/admin/user/managing_customers/changing_customer_email.feature
index 02317b7674..fda68e56d1 100644
--- a/features/admin/user/managing_customers/changing_customer_email.feature
+++ b/features/admin/user/managing_customers/changing_customer_email.feature
@@ -9,7 +9,7 @@ Feature: Changing an email of an existing customer
And there is a customer "Frodo Baggins" with an email "f.baggins@example.com" and a password "ring"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Changing an email of an existing customer
When I want to edit this customer
And I change their email to "strawberry@example.com"
diff --git a/features/admin/user/managing_customers/customer_unique_email_validation.feature b/features/admin/user/managing_customers/customer_unique_email_validation.feature
index 582e06294b..542415d51a 100644
--- a/features/admin/user/managing_customers/customer_unique_email_validation.feature
+++ b/features/admin/user/managing_customers/customer_unique_email_validation.feature
@@ -7,7 +7,7 @@ Feature: Customer uniqueness of email validation
Background:
Given I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Trying to add a new customer with taken email
Given the store has customer "f.baggins@example.com"
When I want to create a new customer
diff --git a/features/admin/user/managing_customers/customer_validation.feature b/features/admin/user/managing_customers/customer_validation.feature
index f9ff6b850a..42896b019b 100644
--- a/features/admin/user/managing_customers/customer_validation.feature
+++ b/features/admin/user/managing_customers/customer_validation.feature
@@ -7,7 +7,7 @@ Feature: Customer validation
Background:
Given I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Trying to add a new customer without an email
When I want to create a new customer
And I specify their first name as "Luke"
@@ -15,7 +15,7 @@ Feature: Customer validation
And I try to add them
Then I should be notified that email is required
- @api @ui
+ @api @todo @ui
Scenario: Trying to specify too short first name for an existing customer
Given the store has customer "l.skywalker@gmail.com"
When I want to edit this customer
@@ -24,7 +24,7 @@ Feature: Customer validation
Then I should be notified that first name should be at least 2 characters long
And the customer "l.skywalker@gmail.com" should still have an empty first name
- @api @ui
+ @api @todo @ui
Scenario: Trying to specify too short last name for an existing customer
Given the store has customer "l.skywalker@gmail.com" with first name "Luke"
When I want to edit this customer
@@ -33,7 +33,7 @@ Feature: Customer validation
Then I should be notified that last name should be at least 2 characters long
And the customer "l.skywalker@gmail.com" should still have an empty last name
- @api @ui
+ @api @todo @ui
Scenario: Trying to remove email from an existing customer
Given the store has customer "l.skywalker@gmail.com"
When I want to edit this customer
@@ -42,7 +42,7 @@ Feature: Customer validation
Then I should be notified that email is required
And the customer "l.skywalker@gmail.com" should still have this email
- @api @ui
+ @api @todo @ui
Scenario: Trying to create customer with wrong email format
When I want to create a new customer
And I specify their email as "wrongemail"
@@ -50,7 +50,7 @@ Feature: Customer validation
Then I should be notified that email is not valid
And the customer with email "wrongemail" should not appear in the store
- @api @ui
+ @api @todo @ui
Scenario: Trying to create customer with wrong email format in strict mode
When I want to create a new customer
And I specify their email as "wrongemail@example..com"
diff --git a/features/admin/user/managing_customers/editing_customer.feature b/features/admin/user/managing_customers/editing_customer.feature
index 1fe8b28fc2..57638adbaf 100644
--- a/features/admin/user/managing_customers/editing_customer.feature
+++ b/features/admin/user/managing_customers/editing_customer.feature
@@ -7,7 +7,7 @@ Feature: Editing a customer
Background:
Given I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Changing first and last name of an existing customer
Given the store has customer "Frodo Baggins" with email "f.baggins@example.com"
When I want to edit this customer
@@ -17,7 +17,7 @@ Feature: Editing a customer
Then I should be notified that it has been successfully edited
And this customer with name "Jon Snow" should appear in the store
- @api @ui
+ @api @todo @ui
Scenario: Removing first and last name from an existing customer
Given the store has customer "Luke Skywalker" with email "l.skywalker@gmail.com"
When I want to edit this customer
@@ -28,7 +28,7 @@ Feature: Editing a customer
And this customer should have an empty first name
And this customer should have an empty last name
- @api @ui
+ @api @todo @ui
Scenario: Making an existing customer subscribed to the newsletter
Given the store has customer "Mike Ross" with email "ross@teammike.com"
When I want to edit this customer
@@ -37,7 +37,7 @@ Feature: Editing a customer
Then I should be notified that it has been successfully edited
And this customer should be subscribed to the newsletter
- @api @ui
+ @api @todo @ui
Scenario: Selecting a group for an existing customer
Given the store has a customer group "Retail"
And the store has customer "Mike Ross" with email "ross@teammike.com"
diff --git a/features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature b/features/admin/user/managing_customers/filtering_customers_by_groups.feature
similarity index 97%
rename from features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature
rename to features/admin/user/managing_customers/filtering_customers_by_groups.feature
index e94cd200fe..a29d643664 100644
--- a/features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature
+++ b/features/admin/user/managing_customers/filtering_customers_by_groups.feature
@@ -14,7 +14,7 @@ Feature: Filtering customers by groups
And this customer belongs to group "Wholesale"
And I am logged in as an administrator
- @api @ui @javascript
+ @api @ui @mink:chromedriver
Scenario: Filtering customers by a group
When I want to see all customers in store
And I filter by group "Retail"
diff --git a/features/admin/user/managing_customers/filtering_customers_by_search.feature b/features/admin/user/managing_customers/filtering_customers_by_search.feature
new file mode 100644
index 0000000000..c976471a9e
--- /dev/null
+++ b/features/admin/user/managing_customers/filtering_customers_by_search.feature
@@ -0,0 +1,33 @@
+@managing_customers
+Feature: Filtering customers by firstname, lastname and email
+ In order to quickly find customers
+ As an Administrator
+ I want to search for a specific customer
+
+ Background:
+ Given there is a customer "Frodo Baggins" with an email "f.baggins@shire.me"
+ And there is a customer "Ghastly Bespoke" with an email "g.bespoke@example.com"
+ And there is a customer "Lirael Abhorsen" with an email "l.abhorsen@example.me"
+ And I am logged in as an administrator
+
+ @ui @api-todo
+ Scenario: Searching customers by email
+ When I want to see all customers in store
+ And I search for customer by "e.me"
+ Then I should see 2 customers on the list
+ And I should see the customer "f.baggins@shire.me" on the list
+ And I should see the customer "l.abhorsen@example.me" on the list
+
+ @ui @api-todo
+ Scenario: Filtering customers by firstname
+ When I want to see all customers in store
+ And I search for customer by "Lirael"
+ Then I should see a single customer on the list
+ And I should see the customer "l.abhorsen@example.me" on the list
+
+ @ui @api-todo
+ Scenario: Filtering customers by lastname
+ When I want to see all customers in store
+ And I search for customer by "Bespoke"
+ Then I should see a single customer on the list
+ And I should see the customer "g.bespoke@example.com" on the list
diff --git a/features/admin/user/managing_customers/resetting_customer_password.feature b/features/admin/user/managing_customers/resetting_customer_password.feature
index 3e06cb2034..8cbf9e6cc9 100644
--- a/features/admin/user/managing_customers/resetting_customer_password.feature
+++ b/features/admin/user/managing_customers/resetting_customer_password.feature
@@ -8,7 +8,7 @@ Feature: Resetting a customer's password
Given there is a user "goodman@example.com" identified by "heisenberg"
And I am logged in as an administrator
- @ui @todo
+ @todo @ui @todo
Scenario: Sending reset password email to a customer
When I view details of the customer "goodman@example.com"
And I reset their password
diff --git a/features/admin/user/managing_customers/seeing_customer_details.feature b/features/admin/user/managing_customers/seeing_customer_details.feature
index e2919aebfd..f22a15c941 100644
--- a/features/admin/user/managing_customers/seeing_customer_details.feature
+++ b/features/admin/user/managing_customers/seeing_customer_details.feature
@@ -6,7 +6,6 @@ Feature: Seeing customer's details
Background:
Given I am logged in as an administrator
- And the store has a customer group Retail
And the store has customer "f.baggins@shire.me" with name "Frodo Baggins" and phone number "666777888" since "2011-01-10 21:00"
@api @ui
@@ -37,7 +36,8 @@ Feature: Seeing customer's details
@api @ui
Scenario: Seeing information about customer groups
- Given the customer belongs to group "Retail"
+ Given the store has a customer group Retail
+ And the customer belongs to group "Retail"
When I view details of the customer "f.baggins@shire.me"
Then this customer should have "Retail" as their group
diff --git a/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature b/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature
index e7d327024a..b0b4f7ed82 100644
--- a/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature
+++ b/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature
@@ -36,4 +36,4 @@ Feature: Seeing customer's orders' statistics
Given customer "lirael.clayr@abhorsen.ok" has fulfilled 12 orders placed on the "Web-UK" channel in each buying 2 "Onion" products
And customer "lirael.clayr@abhorsen.ok" has placed 2 orders on the "Web-UK" channel in each buying 2 "Onion" products
When I view their details
- Then I should see that the average total value of their order in the "Web-UK" channel is "£2,400.00"
+ Then I should see that the average total value of their order in the "Web-UK" channel is "£200.00"
diff --git a/features/admin/user/managing_customers/sorting_customers.feature b/features/admin/user/managing_customers/sorting_customers.feature
new file mode 100644
index 0000000000..8c6d893182
--- /dev/null
+++ b/features/admin/user/managing_customers/sorting_customers.feature
@@ -0,0 +1,74 @@
+@managing_customers
+Feature: Filtering customers by firstname, lastname and email
+ In order to quickly find customers
+ As an Administrator
+ I want to search for a specific customer
+
+ Background:
+ Given the store has customer "f.baggins@shire.me" with name "Frodo Baggins" since "2011-01-10 21:00"
+ And the store has customer "l.abhorsen@example.com" with name "Lirael Abhorsen" since "2020-01-01 10:00"
+ And the store has customer "g.bespoke@example.com" with name "Ghastly Bespoke" since "2000-10-11 15:00"
+ And I am logged in as an administrator
+
+ @ui @api-todo
+ Scenario: Customers are sorted by descending registration date
+ When I want to see all customers in store
+ Then I should see 3 customers on the list
+ And the first customer should be "l.abhorsen@example.com"
+ And the last customer should be "g.bespoke@example.com"
+
+ @ui @api-todo
+ Scenario: Sorting customers by ascending registration date
+ When I want to see all customers in store
+ And I sort customers by ascending registration date
+ Then I should see 3 customers on the list
+ And the first customer should be "g.bespoke@example.com"
+ And the last customer should be "l.abhorsen@example.com"
+
+ @ui @api-todo
+ Scenario: Sorting customers by descending email
+ When I want to see all customers in store
+ And I sort customers by descending email
+ Then I should see 3 customers on the list
+ And the first customer should be "l.abhorsen@example.com"
+ And the last customer should be "f.baggins@shire.me"
+
+ @ui @api-todo
+ Scenario: Sorting customers by ascending email
+ When I want to see all customers in store
+ And I sort customers by ascending email
+ Then I should see 3 customers on the list
+ And the first customer should be "f.baggins@shire.me"
+ And the last customer should be "l.abhorsen@example.com"
+
+ @ui @api-todo
+ Scenario: Sorting customers by descending first name
+ When I want to see all customers in store
+ And I sort customers by descending first name
+ Then I should see 3 customers on the list
+ And the first customer should be "l.abhorsen@example.com"
+ And the last customer should be "f.baggins@shire.me"
+
+ @ui @api-todo
+ Scenario: Sorting customers by ascending first name
+ When I want to see all customers in store
+ And I sort customers by ascending first name
+ Then I should see 3 customers on the list
+ And the first customer should be "f.baggins@shire.me"
+ And the last customer should be "l.abhorsen@example.com"
+
+ @ui @api-todo
+ Scenario: Sorting customers by descending last name
+ When I want to see all customers in store
+ And I sort customers by descending last name
+ Then I should see 3 customers on the list
+ And the first customer should be "g.bespoke@example.com"
+ And the last customer should be "l.abhorsen@example.com"
+
+ @ui @api-todo
+ Scenario: Sorting customers by ascending last name
+ When I want to see all customers in store
+ And I sort customers by ascending last name
+ Then I should see 3 customers on the list
+ And the first customer should be "l.abhorsen@example.com"
+ And the last customer should be "g.bespoke@example.com"
diff --git a/features/admin/user/managing_customers/toggling_customer_account.feature b/features/admin/user/managing_customers/toggling_customer_account.feature
index d2844b4e54..75c25fa678 100644
--- a/features/admin/user/managing_customers/toggling_customer_account.feature
+++ b/features/admin/user/managing_customers/toggling_customer_account.feature
@@ -7,7 +7,7 @@ Feature: Toggling a customer account
Background:
Given I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Enabling a customer account
Given there is disabled customer account "f.baggins@example.com" with password "psw"
When I want to enable "f.baggins@example.com"
@@ -16,7 +16,7 @@ Feature: Toggling a customer account
Then I should be notified that it has been successfully edited
And this customer should be enabled
- @api @ui
+ @api @todo @ui
Scenario: Disabling a customer account
Given there is enabled customer account "f.baggins@example.com" with password "psw"
When I want to disable "f.baggins@example.com"
diff --git a/features/admin/user/managing_customers/verifying_customer_account.feature b/features/admin/user/managing_customers/verifying_customer_account.feature
index 3060e99fb7..0c4696910c 100644
--- a/features/admin/user/managing_customers/verifying_customer_account.feature
+++ b/features/admin/user/managing_customers/verifying_customer_account.feature
@@ -7,7 +7,7 @@ Feature: Toggling a customer account
Background:
Given I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Verifying customer account
Given there is enabled customer account "f.baggins@example.com" with password "psw"
When I want to verify "f.baggins@example.com"
diff --git a/features/admin/user/managing_users/changing_shop_user_password.feature b/features/admin/user/managing_users/changing_shop_user_password.feature
index b05422d149..b4241d5b08 100644
--- a/features/admin/user/managing_users/changing_shop_user_password.feature
+++ b/features/admin/user/managing_users/changing_shop_user_password.feature
@@ -9,7 +9,7 @@ Feature: Changing shop user's password
And there is a user "kibsoon@example.com" identified by "goodGuy"
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Changing a password of a shop user
When I change the password of user "kibsoon@example.com" to "veryGoodGuy"
Then I should be notified that it has been successfully edited
diff --git a/features/domain/cart/deleting_expired_carts_automatically.feature b/features/domain/cart/deleting_expired_carts_automatically.feature
deleted file mode 100644
index 3e4c453d2c..0000000000
--- a/features/domain/cart/deleting_expired_carts_automatically.feature
+++ /dev/null
@@ -1,20 +0,0 @@
-@shopping_cart
-Feature: Deleting expired carts automatically
- In order to remove started but not finished orders after 2 days of idleness
- As an Administrator
- I want to have expired carts automatically deleted
-
- Background:
- Given the store operates on a single channel in "United States"
-
- @domain
- Scenario: Having cart deleted after 4 days of idleness
- Given a customer "john.doe@gmail.com" added something to cart
- And he abandoned the cart 4 days ago
- Then this cart should be automatically deleted
-
- @domain
- Scenario: Having idle cart in registry if expiration time has not been reached
- Given a customer "john.doe@gmail.com" added something to cart
- And he abandoned the cart 1 day ago
- Then this cart should not be deleted
diff --git a/features/domain/order/cancelling_unpaid_orders_automatically.feature b/features/domain/order/cancelling_unpaid_orders_automatically.feature
deleted file mode 100644
index bcf3aa78e1..0000000000
--- a/features/domain/order/cancelling_unpaid_orders_automatically.feature
+++ /dev/null
@@ -1,27 +0,0 @@
-@managing_orders
-Feature: Cancelling unpaid orders automatically
- In order to get rid of completed orders after 5 days of being unpaid
- As an Administrator
- I want to have unpaid orders automatically cancelled
-
- Background:
- Given the store operates on a single channel in "United States"
- And the store has a product "PHP T-Shirt" priced at "$10.00" in "United States" channel
- And the store ships everywhere for Free
- And the store allows paying with "Paypal Express Checkout"
-
- @domain
- Scenario: Having order cancelled after 10 days of being unpaid
- Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
- And the customer bought a single "PHP T-Shirt"
- And the customer chose "Free" shipping method to "United States" with "Paypal Express Checkout" payment
- When this order has not been paid for 10 days
- Then this order should be automatically cancelled
-
- @domain
- Scenario: Having unpaid order not cancelled if expiration time has not been reached
- Given there is a customer "john.doe@gmail.com" that placed an order "#00000022"
- And the customer bought a single "PHP T-Shirt"
- And the customer chose "Free" shipping method to "United States" with "Paypal Express Checkout" payment
- When this order has not been paid for 2 days
- Then this order should not be cancelled
diff --git a/features/domain/order/deleting_order.feature b/features/domain/order/deleting_order.feature
deleted file mode 100644
index 19e260a763..0000000000
--- a/features/domain/order/deleting_order.feature
+++ /dev/null
@@ -1,45 +0,0 @@
-@managing_orders
-Feature: Deleting an order
- In order to to remove test, obsolete or incorrect orders
- As an Administrator
- I want to be able to delete an order with all it's details from the registry
-
- Background:
- Given the store operates on a single channel in "United States"
- And the store has a product "PHP T-Shirt"
- And the store ships everywhere for Free
- And the store allows paying with "Cash on Delivery"
- And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
- And the customer bought a single "PHP T-Shirt"
- And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
- And I am logged in as an administrator
-
- @domain
- Scenario: Deleted order should disappear from the registry
- When I delete the order "#00000022"
- Then this order should not exist in the registry
-
- @domain
- Scenario: Payments of a deleted order should disappear from the registry
- When I delete the order "#00000022"
- Then there should be no "Cash on Delivery" payments in the registry
-
- @domain
- Scenario: Shipments of a deleted order should disappear from the registry
- When I delete the order "#00000022"
- Then there should be no shipments with "Free" shipping method in the registry
-
- @domain
- Scenario: Order items are deleted together with an order
- When I delete the order "#00000022"
- Then the order item with product "PHP T-Shirt" should not exist
-
- @domain
- Scenario: Order adjustments are deleted together with an order
- When I delete the order "#00000022"
- Then adjustments of this order should not exist
-
- @domain
- Scenario: Billing and shipping addresses are deleted with an order
- When I delete the order "#00000022"
- Then billing and shipping addresses of this order should not exist
diff --git a/features/domain/product/deleting_old_channel_pricing_entry_logs.feature b/features/domain/product/deleting_old_channel_pricing_entry_logs.feature
deleted file mode 100644
index ad40222dd7..0000000000
--- a/features/domain/product/deleting_old_channel_pricing_entry_logs.feature
+++ /dev/null
@@ -1,31 +0,0 @@
-@managing_price_history
-Feature: Deleting old channel pricing entry logs
- In order to keep the price history slim
- As an Administrator
- I want to delete old channel pricing entry logs
-
- Background:
- Given the store operates on a single channel in "United States"
- And it is "2022-03-14" now
- And the store has a product "PHP T-Shirt" priced at "$10.00"
- And on "2022-03-20" its price changed to "$20.00"
- And on "2022-03-29" its original price changed to "$25.00"
- And on "2022-04-14" its price changed to "$15.00" and original price to "$30.00"
- And on "2022-04-20" its original price has been removed
- And it is "2022-04-29" now
-
- @domain
- Scenario: Deleting price history older than 90 days
- When I delete price history older than 90 days
- Then there should be 5 price history entries for this product
-
- @domain
- Scenario: Deleting price history older than 30 days
- When I delete price history older than 30 days
- Then there should be 2 price history entries for this product
- And this product should have no entry with original price changed to "$25.00"
-
- @domain
- Scenario: Deleting price history older than 1 day
- When I delete price history older than 1 day
- Then this product's price history should be empty
diff --git a/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature b/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature
index 7fa12158a4..0387928dd8 100644
--- a/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature
+++ b/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature
@@ -13,7 +13,7 @@ Feature: Assigning customer's IP address to a placed order
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui
+ @todo @ui
Scenario: Assigning customer's IP address to a newly placed order
Given I have product "PHP T-Shirt" in the cart
And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow"
diff --git a/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature b/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature
index 7361172e46..6be63148ba 100644
--- a/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature
+++ b/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature
@@ -13,7 +13,7 @@ Feature: Leaving additional request notes on my order during checkout
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui @api
+ @todo @ui @api
Scenario: Adding note on the checkout summary step
Given I have product "PHP T-Shirt" in the cart
And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow"
diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature
index 08890889f4..ac71f2e99f 100644
--- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature
+++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature
@@ -16,7 +16,7 @@ Feature: Placing an order on a single channel store
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui
+ @todo @ui
Scenario: Placing an order in a channels base currency
Given I have product "PHP T-Shirt" in the cart
And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow"
@@ -24,7 +24,7 @@ Feature: Placing an order on a single channel store
And I confirm my order
Then the administrator should see that order placed by "customer@example.com" has "USD" currency
- @ui @no-api
+ @todo @ui @no-api
Scenario: Placing an order in a channels base currency displaying prices in other currency
Given that channel also allows to shop using the "CAD" currency
And I had product "PHP T-Shirt" in the cart
diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature
index 3a42742c0e..4ff38f03b2 100644
--- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature
+++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature
@@ -17,7 +17,7 @@ Feature: Placing an order on multiple channels with different currency
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui @api
+ @todo @ui @api
Scenario: Placing an order in a channels base currency
Given I changed my current channel to "United States"
And I have product "PHP T-Shirt" in the cart
@@ -26,7 +26,7 @@ Feature: Placing an order on multiple channels with different currency
And I confirm my order
Then the administrator should see that order placed by "customer@example.com" has "USD" currency
- @ui @api
+ @todo @ui @api
Scenario: Placing an order on a different channel with same currency
Given I changed my current channel to "Colombia"
And I had product "PHP T-Shirt" in the cart
diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature
index 24ebe67960..91dc157d0a 100644
--- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature
+++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature
@@ -17,7 +17,7 @@ Feature: Placing an order on multiple channels with same currency
And there is a customer account "customer@example.com" identified by "sylius"
And I am logged in as "customer@example.com"
- @ui
+ @todo @ui
Scenario: Placing an order in a channels base currency
Given I changed my current channel to "Web"
And I have product "PHP T-Shirt" in the cart
@@ -26,7 +26,7 @@ Feature: Placing an order on multiple channels with same currency
And I confirm my order
Then the administrator should see that order placed by "customer@example.com" has "USD" currency
- @ui
+ @todo @ui
Scenario: Placing an order on a different channel with same currency
Given I changed my current channel to "Mobile"
And I had product "PHP T-Shirt" in the cart
diff --git a/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature b/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature
index 02be72c5d7..35653155d9 100644
--- a/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature
+++ b/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature
@@ -9,13 +9,13 @@ Feature: Applying catalog promotions for product created in catalog promotions s
And the store classifies its products as "Clothes" and "Dishes"
And I am logged in as an administrator
- @ui @mink:chromedriver @no-api
+ @todo @ui @mink:chromedriver @no-api
Scenario: Applying catalog promotion on newly created simple product
Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon
When I create a new simple product "T-Shirt" priced at "$20.00" with "Clothes" taxon in the "United States" channel
Then the visitor should see "$14.00" as the price of the "T-Shirt" product in the "United States" channel
- @api @ui
+ @api @todo @ui
Scenario: Applying catalog promotion on newly created product variant
Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon
And the store has a "T-Shirt" configurable product
@@ -23,7 +23,7 @@ Feature: Applying catalog promotions for product created in catalog promotions s
When I create a new "PHP T-Shirt" variant priced at "$20.00" for "T-Shirt" product in the "United States" channel
Then the visitor should see "$14.00" as the price of the "T-Shirt" product in the "United States" channel
- @api @ui
+ @api @todo @ui
Scenario: Not applying catalog promotion on newly created product variant if it's not eligible
Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon
And the store has a "Plate" configurable product
diff --git a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature
index b7dd344f27..1cf3d378fc 100644
--- a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature
+++ b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature
@@ -14,12 +14,12 @@ Feature: Not reapplying catalog promotions on variant once its prices changes
And there is disabled catalog promotion "Surprise sale" between "2021-07-01" and "2022-05-04" available in "Web-US" channel that reduces price by "90%" and applies on "PHP T-Shirt" variant
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Changing the price of the variant
When I change the price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel
Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel
- @api @ui
+ @api @todo @ui
Scenario: Changing the original price of the variant
When I change the original price of the "PHP T-Shirt" product variant to "$105.00" in "Web-US" channel
Then the visitor should see "$100.00" as the price of the "T-Shirt" product in the "Web-US" channel
diff --git a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature
index c9cd8bf966..556782973c 100644
--- a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature
+++ b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature
@@ -16,14 +16,14 @@ Feature: Not reapplying catalog promotions on variants once the product’s taxo
And there is disabled catalog promotion "Surprise sale" between "2021-07-01" and "2022-05-04" available in "Web-US" channel that reduces price by "90%" and applies on "Dishes" taxon
And I am logged in as an administrator
- @api @ui
+ @api @todo @ui
Scenario: Changing products taxon to taxon with scheduled catalog promotion
When I change that the "T-Shirt" product does not belong to the "Clothes" taxon
And I add "Shirts" taxon to the "T-Shirt" product
Then the visitor should see that the "PHP T-Shirt" variant is not discounted
And the visitor should still see "$100.00" as the price of the "T-Shirt" product in the "Web-US" channel
- @api @ui
+ @api @todo @ui
Scenario: Changing products taxon to taxon with disabled catalog promotion
When I change that the "T-Shirt" product does not belong to the "Clothes" taxon
And I add "Dishes" taxon to the "T-Shirt" product
diff --git a/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature b/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature
index a0bdae1487..5f6d8c2d39 100644
--- a/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature
+++ b/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature
@@ -7,7 +7,7 @@ Feature: Paying with paypal during checkout
Background:
Given the store operates on a single channel in "United States"
And there is a user "john@example.com" identified by "password123"
- And the store has a payment method "PayPal" with a code "PAYPAL" and Paypal Express Checkout gateway
+ And the store has a payment method "PayPal" with a code "PAYPAL" and "Paypal Express Checkout" gateway
And the store has a product "PHP T-Shirt" priced at "$19.99"
And the store ships everywhere for Free
And I am logged in as "john@example.com"
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature
deleted file mode 100644
index 6de013563e..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature
+++ /dev/null
@@ -1,60 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying catalog promotions after editing their actions
- In order to have proper discounts per catalog promotion action
- As a Store Owner
- I want to have discounts reapplied in product catalog once the action of catalog promotion changes
-
- Background:
- Given the store operates on a channel identified by "Web-US" code
- And the store has a "T-Shirt" configurable product
- And this product has "PHP T-Shirt" variant priced at "$20.00" in "Web-US" channel
- And this product has "Python T-Shirt" variant priced at "$10.00" in "Web-US" channel
- And there is a catalog promotion "Winter sale" that reduces price by "50%" and applies on "PHP T-Shirt" variant
- And I am logged in as an administrator
-
- @api @ui @javascript
- Scenario: Reapplying catalog promotion after adding a new action to it
- Given there is a catalog promotion with "Summer_sale" code and "Summer sale" name
- And it applies on "Python T-Shirt" variant
- When I modify a catalog promotion "Summer sale"
- And I add action that gives "25%" percentage discount
- And I save my changes
- And the visitor view "Python T-Shirt" variant
- Then this product variant price should be "$7.50"
- And this product original price should be "$10.00"
-
- @api @ui @javascript
- Scenario: Reapplying catalog promotion after editing its action
- When I modify a catalog promotion "Winter sale"
- And I edit its action so that it reduces price by "25%"
- And I save my changes
- And the visitor view "PHP T-Shirt" variant
- Then this product variant price should be "$15.00"
- And this product original price should be "$20.00"
-
- @api @ui @javascript
- Scenario: Reapplying catalog promotion after removing and adding new action
- When I modify a catalog promotion "Winter sale"
- And I remove its every action
- And I save my changes
- And I add action that gives "10%" percentage discount
- And I save my changes
- And the visitor view "PHP T-Shirt" variant
- Then this product variant price should be "$18.00"
- And this product original price should be "$20.00"
-
- @api @ui @javascript
- Scenario: Reapplying catalog promotion after adding another action
- When I modify a catalog promotion "Winter sale"
- And I add another action that gives "10%" percentage discount
- And I save my changes
- And the visitor view "PHP T-Shirt" variant
- Then this product variant price should be "$9.00"
- And this product original price should be "$20.00"
-
- @api @ui @javascript
- Scenario: Restoring original price after removing action from catalog promotion configuration
- When I modify a catalog promotion "Winter sale"
- And I remove its every action
- And I save my changes
- Then the visitor should see that the "PHP T-Shirt" variant is not discounted
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature
deleted file mode 100644
index 9e8adf5730..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature
+++ /dev/null
@@ -1,71 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying catalog promotion after editing their scopes
- In order to have proper discounts per catalog promotion action
- As a Store Owner
- I want to have catalog promotion reapplied in product catalog once the scope of catalog promotion changes
-
- Background:
- Given the store operates on a single channel in "United States"
- And the store classifies its products as "Clothes" and "Dishes"
- And the store has a "T-Shirt" configurable product
- And this product belongs to "Clothes"
- And this product has "PHP T-Shirt" variant priced at "$20.00"
- And the store has a "Mug" configurable product
- And this product belongs to "Dishes"
- And this product has "PHP Mug" variant priced at "$5.00"
- And this product has "Expensive Mug" variant priced at "$50.00"
- And there is a catalog promotion "Summer sale" that reduces price by "50%" and applies on "PHP T-Shirt" variant
- And I am logged in as an administrator
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after adding a new scope to it
- Given there is a catalog promotion named "Mug sale"
- When I modify a catalog promotion "Mug sale"
- And I add scope that applies on "Expensive Mug" variant and "PHP Mug" variant
- And I add action that gives "50%" percentage discount
- And I save my changes
- Then the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$25.00" with "Mug sale" promotion
- And the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$2.50" with "Mug sale" promotion
-
- @api @ui @javascript
- Scenario: Reapplying catalog promotion after removing its scopes
- When I modify a catalog promotion "Summer sale"
- And I remove its every scope
- And I save my changes
- Then the visitor should see that the "PHP T-Shirt" variant is not discounted
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after adding another scope
- When I modify a catalog promotion "Summer sale"
- And I add another scope that applies on "PHP Mug" variant
- And I save my changes
- Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$2.50" with "Summer sale" promotion
- And the visitor should still see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after editing the variant in its scope
- When I edit "Summer sale" catalog promotion to be applied on "Expensive Mug" variant
- Then the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$25.00" with "Summer sale" promotion
- And the visitor should see that the "PHP T-Shirt" variant is not discounted
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after editing the taxon in its scope
- Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "Clothes" taxon
- When I edit "Winter sale" catalog promotion to be applied on "Dishes" taxon
- Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion
- And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after editing the product in its scope
- Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "T-Shirt" product
- When I edit "Winter sale" catalog promotion to be applied on "Mug" product
- Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion
- And the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$35.00" with "Winter sale" promotion
- And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion
-
- @api @ui @mink:chromedriver
- Scenario: Reapplying catalog promotion after editing the type of its scope
- Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "PHP T-Shirt" variant
- When I edit "Winter sale" catalog promotion to be applied on "Dishes" taxon
- Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion
- And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature
deleted file mode 100644
index f5d2745ba3..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature
+++ /dev/null
@@ -1,31 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying catalog promotions on variant once its prices changes
- In order to have proper discounts on variants
- As a Store Owner
- I want to have discounts reapplied on variant once its prices changes
-
- Background:
- Given the store operates on a channel named "Web-US" with hostname "web-us"
- And the store has a "T-Shirt" configurable product
- And this product has "PHP T-Shirt" variant priced at "$100.00" in "Web-US" channel
- And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant
- And there is another catalog promotion "Christmas sale" available in "Web-US" channel that reduces price by "50%" and applies on "PHP T-Shirt" variant
- And I am logged in as an administrator
-
- @api @ui
- Scenario: Changing the price of the variant
- When I change the price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel
- Then the visitor should still see "$35.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should still see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel
-
- @api @ui
- Scenario: Changing the original price of the variant
- When I change the original price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel
- Then the visitor should see "$17.50" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$50.00" as the original price of the "T-Shirt" product in the "Web-US" channel
-
- @api @ui
- Scenario: Removing the original price of the variant
- When I remove the original price of the "PHP T-Shirt" product variant in "Web-US" channel
- Then the visitor should see "$12.25" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$35.00" as the original price of the "T-Shirt" product in the "Web-US" channel
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature
deleted file mode 100644
index b9b3f3f1e3..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature
+++ /dev/null
@@ -1,27 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying catalog promotions on variants once the product’s taxon changes
- In order to have proper discounts in product catalog
- As a Store Owner
- I want to have discounts reapplied on variants once the product’s taxon changes
-
- Background:
- Given the store operates on a channel named "Web-US" with hostname "web-us"
- And the store classifies its products as "Clothes" and "Dishes"
- And the store has a "T-Shirt" configurable product
- And this product belongs to "Clothes"
- And this product has "PHP T-Shirt" variant priced at "$100.00"
- And the store has a "Mug" configurable product
- And this product has "PHP Mug" variant priced at "$10.00"
- And there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "Clothes" taxon
- And there is another catalog promotion "Summer sale" that reduces price by "50%" and applies on "Dishes" taxon
- And I am logged in as an administrator
-
- @api @ui
- Scenario: Removing a taxon from a product
- When I change that the "T-Shirt" product does not belong to the "Clothes" taxon
- Then the visitor should see that the "PHP T-Shirt" variant is not discounted
-
- @api @ui
- Scenario: Adding a taxon to a product
- When I assign the "Dishes" taxon to the "Mug" product
- Then the visitor should see that the "PHP Mug" variant is discounted from "$10.00" to "$5.00" with "Summer sale" promotion
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature
deleted file mode 100644
index 5be099715a..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature
+++ /dev/null
@@ -1,46 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying multiple catalog promotions after editing their channels
- In order to have proper discounts in different channels
- As a Store Owner
- I want to have discounts reapplied in product catalog once the channels of catalog promotion changes
-
- Background:
- Given the store operates on a channel named "Web-US" with hostname "web-us"
- And the store operates on another channel named "Web-GB" with hostname "web-gb"
- And the store has a "T-Shirt" configurable product
- And this product has "PHP T-Shirt" variant priced at "$100.00" in "Web-US" channel
- And "PHP T-Shirt" variant priced at "$100.00" in "Web-GB" channel
- And this product is available in "Web-US" channel and "Web-GB" channel
- And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant
- And there is another catalog promotion "Christmas sale" available in "Web-US" channel and "Web-GB" channel that reduces price by "50%" and applies on "PHP T-Shirt" variant
- And I am logged in as an administrator
-
- @api @ui
- Scenario: Removing only modified catalog promotion after removing its channel
- When I make the "Winter sale" catalog promotion unavailable in the "Web-US" channel
- Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel
-
- @api @ui
- Scenario: Reapplying catalog promotion after adding new channel to them
- When I make "Winter sale" catalog promotion available in the "Web-GB" channel
- Then the visitor should see "$35.00" as the price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should still see "$35.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should still see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel
-
- @api @ui
- Scenario: Reapplying catalog promotion after switching availability in channels
- When I switch "Winter sale" catalog promotion availability from the "Web-US" channel to the "Web-GB" channel
- Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$35.00" as the price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel
-
- @api @ui
- Scenario: Reapplying catalog promotion after switching availability in channels
- When I make the "Christmas sale" catalog promotion unavailable in the "Web-US" channel
- Then the visitor should see "$70.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel
diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature
deleted file mode 100644
index 9a08915c52..0000000000
--- a/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature
+++ /dev/null
@@ -1,37 +0,0 @@
-@applying_catalog_promotions
-Feature: Reapplying single catalog promotion after editing its channels
- In order to have proper discounts in different channels
- As a Store Owner
- I want to have discounts reapplied in product catalog once the channels of catalog promotion changes
-
- Background:
- Given the store operates on a channel named "Web-US" with hostname "web-us"
- And the store operates on another channel named "Web-GB" with hostname "web-gb"
- And the store has a "T-Shirt" configurable product
- And this product has "PHP T-Shirt" variant priced at "$20.00" in "Web-US" channel
- And "PHP T-Shirt" variant priced at "$30.00" in "Web-GB" channel
- And this product is available in "Web-US" channel and "Web-GB" channel
- And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant
- And I am logged in as an administrator
-
- @api @ui
- Scenario: Removing applied catalog promotion after removing its channel
- When I make this catalog promotion unavailable in the "Web-US" channel
- Then the visitor should see "$20.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see this variant is not discounted
-
- @api @ui
- Scenario: Reapplying catalog promotion after adding new channel to them
- When I make this catalog promotion available in the "Web-GB" channel
- Then the visitor should see "$21.00" as the price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should see "$30.00" as the original price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should still see "$14.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should still see "$20.00" as the original price of the "T-Shirt" product in the "Web-US" channel
-
- @api @ui
- Scenario: Reapplying catalog promotion after switching availability in channels
- When I switch this catalog promotion availability from the "Web-US" channel to the "Web-GB" channel
- Then the visitor should see "$20.00" as the price of the "T-Shirt" product in the "Web-US" channel
- And the visitor should see this variant is not discounted
- And the visitor should see "$21.00" as the price of the "T-Shirt" product in the "Web-GB" channel
- And the visitor should see "$30.00" as the original price of the "T-Shirt" product in the "Web-GB" channel
diff --git a/package.json b/package.json
index cb27498202..4d95e26cc5 100644
--- a/package.json
+++ b/package.json
@@ -14,20 +14,25 @@
"watch": "encore dev --watch"
},
"dependencies": {
+ "@sylius-ui/admin": "file:src/Sylius/Bundle/AdminBundle",
"chart.js": "^3.7.1",
"jquery": "^3.5.0",
"jquery.dirtyforms": "^2.0.0",
"lightbox2": "^2.9.0",
"semantic-ui-css": "^2.2.0",
- "slick-carousel": "^1.8.1"
+ "slick-carousel": "^1.8.1",
+ "@symfony/ux-autocomplete": "file:vendor/symfony/ux-autocomplete/assets",
+ "@symfony/ux-live-component": "file:vendor/symfony/ux-live-component/assets"
},
"devDependencies": {
"@babel/core": "^7.0.0",
- "@babel/polyfill": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.18.9",
+ "@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.18.10",
"@babel/register": "^7.0.0",
+ "@hotwired/stimulus": "^3.0.0",
"@semantic-ui-react/css-patch": "^1.1.2",
+ "@symfony/stimulus-bridge": "^3.2.2",
"@symfony/webpack-encore": "^3.1.0",
"eslint": "^8.23.0",
"eslint-config-airbnb-base": "^15.0.0",
@@ -35,6 +40,7 @@
"eslint-plugin-import": "^2.26.0",
"sass": "^1.54.8",
"sass-loader": "^13.0.0",
+ "tom-select": "^2.2.2",
"yargs": "^17.5.1"
},
"engines": {
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 4d253a07ea..f85742315a 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -25,11 +25,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/AddressingBundle/Form/Type/ProvinceCodeChoiceType.php
- -
- message: "#^Method Sylius\\\\Bundle\\\\AddressingBundle\\\\Form\\\\Type\\\\ZoneChoiceType\\:\\:__construct\\(\\) has parameter \\$scopeTypes with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/AddressingBundle/Form/Type/ZoneChoiceType.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\AddressingBundle\\\\Form\\\\Type\\\\ZoneChoiceType\\:\\:__construct\\(\\) has parameter \\$zoneRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
count: 1
@@ -2405,11 +2400,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/CoreBundle/Collector/SyliusCollector.php
- -
- message: "#^If condition is always false\\.$#"
- count: 1
- path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php
-
-
message: "#^If condition is always false\\.$#"
count: 1
@@ -3575,11 +3565,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/CoreBundle/Form/EventSubscriber/CustomerRegistrationFormSubscriber.php
- -
- message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Form\\\\Extension\\\\CountryTypeExtension\\:\\:__construct\\(\\) has parameter \\$countryRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
- count: 1
- path: src/Sylius/Bundle/CoreBundle/Form/Extension/CountryTypeExtension.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Form\\\\Extension\\\\LocaleTypeExtension\\:\\:__construct\\(\\) has parameter \\$localeRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#"
count: 1
@@ -3795,11 +3780,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/CoreBundle/MessageHandler/Admin/Account/RequestResetPasswordEmailHandler.php
- -
- message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\MessageHandler\\\\Admin\\\\Account\\\\SendResetPasswordEmailHandler\\:\\:__construct\\(\\) has parameter \\$userRepository with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface but does not specify its types\\: T$#"
- count: 1
- path: src/Sylius/Bundle/CoreBundle/MessageHandler/Admin/Account/SendResetPasswordEmailHandler.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Migrations\\\\Version20171003103916\\:\\:getProductAttributes\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
@@ -4125,11 +4105,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/LocaleBundle/SyliusLocaleBundle.php
- -
- message: "#^If condition is always false\\.$#"
- count: 1
- path: src/Sylius/Bundle/OrderBundle/Command/RemoveExpiredCartsCommand.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\OrderBundle\\\\Context\\\\SessionBasedCartContext\\:\\:__construct\\(\\) has parameter \\$orderRepository with generic interface Sylius\\\\Component\\\\Order\\\\Repository\\\\OrderRepositoryInterface but does not specify its types\\: T$#"
count: 1
@@ -4850,51 +4825,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:getRenderedEvents\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingBlock\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingEvent\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingEvent\\(\\) has parameter \\$eventNames with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingBlock\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingEvent\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingEvent\\(\\) has parameter \\$eventNames with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TraceableTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateBlockRenderer.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TraceableTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateEventRenderer.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DependencyInjection\\\\SyliusUiExtension\\:\\:loadEvents\\(\\) has parameter \\$eventsConfig with no value type specified in iterable type array\\.$#"
count: 1
@@ -4905,56 +4835,6 @@ parameters:
count: 1
path: src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlock\\:\\:__construct\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlock\\:\\:getContext\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlockRegistry\\:\\:__construct\\(\\) has parameter \\$eventsToTemplateBlocks with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistry.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\DelegatingTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/DelegatingTemplateEventRenderer.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\HtmlDebugTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateBlockRenderer.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\HtmlDebugTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateEventRenderer.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TemplateBlockRendererInterface\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/TemplateBlockRendererInterface.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TemplateEventRendererInterface\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/TemplateEventRendererInterface.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TwigTemplateBlockRenderer\\:\\:__construct\\(\\) has parameter \\$contextProviders with no value type specified in iterable type iterable\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php
-
- -
- message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TwigTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php
-
-
message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Storage\\\\FilterStorage\\:\\:all\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
@@ -5985,26 +5865,6 @@ parameters:
count: 1
path: src/Sylius/Component/Core/Provider/ProductVariantMap/ProductVariantsMapProviderInterface.php
- -
- message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProvider\\:\\:constructOptionsMap\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php
-
- -
- message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProvider\\:\\:provideVariantsPrices\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php
-
- -
- message: "#^PHPDoc tag @var for variable \\$appliedPromotions contains generic class Doctrine\\\\Common\\\\Collections\\\\ArrayCollection but does not specify its types\\: TKey, T$#"
- count: 1
- path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php
-
- -
- message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProviderInterface\\:\\:provideVariantsPrices\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProviderInterface.php
-
-
message: "#^Method Sylius\\\\Component\\\\Core\\\\Repository\\\\OrderItemRepositoryInterface\\:\\:findOneByIdAndCustomer\\(\\) has parameter \\$id with no type specified\\.$#"
count: 1
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 2bce4c7ad0..96f9de35b8 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -37,6 +37,9 @@ parameters:
# Temporary exclusion during upgrade to API Platform 3
- 'src/Sylius/Bundle/ApiBundle/**.php'
+ # Random errors related to Template Events (we're going to replace them with Twig Events anyway)
+ - 'src/Sylius/Bundle/UiBundle/Console/Command/DebugTemplateEventCommand.php'
+
ignoreErrors:
- '/(Interface|Class) [a-zA-Z\\]+ specifies template type (\w+) of interface [a-zA-Z\\]+ as [a-zA-Z\\]+ (of [a-zA-Z\\]+ )?but it''s already specified as/' # turns off a weird generics check behavior, we are basing on Psalm for generics checks
- '/Access to an undefined property Doctrine\\Common\\Collections\\ArrayCollection/'
@@ -48,3 +51,4 @@ parameters:
- '/Method Sylius\\Component\\(\w+)\\Model\\(\w+)\:\:getId\(\) has no return type specified./'
- '/Method [a-zA-z\\]+Filter\:\:filterProperty\(\) has parameter \$value with no type specified./'
- '/Method [a-zA-z\\]+Persister\:\:(persist|remove|supports)\(\) has parameter \$data with no type specified./'
+ - '/Method Sylius\\Bundle\\AdminBundle\\Twig\\Component\\[a-zA-Z\\]+\:\:getDataModelValue\(\) is unused./'
diff --git a/rector.php b/rector.php
index 6f399dadbd..47f27d17ab 100644
--- a/rector.php
+++ b/rector.php
@@ -2,21 +2,12 @@
declare(strict_types=1);
-use Rector\Core\Configuration\Option;
-use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
-use Rector\Php74\Rector\Property\TypedPropertyRector;
+use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
-use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
-return static function (ContainerConfigurator $containerConfigurator): void
+return static function (RectorConfig $config): void
{
- $containerConfigurator->import(LevelSetList::UP_TO_PHP_80);
-
- $parameters = $containerConfigurator->parameters();
- $parameters->set(Option::AUTO_IMPORT_NAMES, true);
- $parameters->set(Option::IMPORT_SHORT_CLASSES, false);
-
- $services = $containerConfigurator->services();
- $services->set(TypedPropertyRector::class);
- $services->set(ClosureToArrowFunctionRector::class);
+ $config->sets([
+ LevelSetList::UP_TO_PHP_82
+ ]);
};
diff --git a/src/Sylius/Behat/Client/ResponseChecker.php b/src/Sylius/Behat/Client/ResponseChecker.php
index b1588ec869..789325d4c9 100644
--- a/src/Sylius/Behat/Client/ResponseChecker.php
+++ b/src/Sylius/Behat/Client/ResponseChecker.php
@@ -108,14 +108,12 @@ final class ResponseChecker implements ResponseCheckerInterface
return $response->getStatusCode() === Response::HTTP_OK;
}
- /** @param string|int $value */
- public function hasValue(Response $response, string $key, $value): bool
+ public function hasValue(Response $response, string $key, bool|int|string|null $value): bool
{
return $this->getResponseContentValue($response, $key) === $value;
}
- /** @param string|int $value */
- public function hasValueInCollection(Response $response, string $key, $value): bool
+ public function hasValueInCollection(Response $response, string $key, bool|int|string $value): bool
{
return in_array($value, $this->getResponseContentValue($response, $key), true);
}
@@ -176,6 +174,15 @@ final class ResponseChecker implements ResponseCheckerInterface
return true;
}
+ public function hasValueInSubresourceObject(Response $response, string $subResource, string $key, bool|int|string $expectedValue): bool
+ {
+ $resource = $this->getResponseContentValue($response, $subResource);
+
+ $this->assertIsArray($resource);
+
+ return $resource[$key] === $expectedValue;
+ }
+
/** @param string|array $value */
public function hasItemOnPositionWithValue(Response $response, int $position, string $key, $value): bool
{
diff --git a/src/Sylius/Behat/Client/ResponseCheckerInterface.php b/src/Sylius/Behat/Client/ResponseCheckerInterface.php
index b775005011..7397a8b4d2 100644
--- a/src/Sylius/Behat/Client/ResponseCheckerInterface.php
+++ b/src/Sylius/Behat/Client/ResponseCheckerInterface.php
@@ -45,7 +45,7 @@ interface ResponseCheckerInterface
public function hasCollection(Response $response): bool;
- public function hasValue(Response $response, string $key, int|string $value): bool;
+ public function hasValue(Response $response, string $key, bool|int|string|null $value): bool;
public function hasValueInCollection(Response $response, string $key, int|string $value): bool;
@@ -65,6 +65,13 @@ interface ResponseCheckerInterface
array $expectedValues,
): bool;
+ public function hasValueInSubresourceObject(
+ Response $response,
+ string $subResource,
+ string $key,
+ bool|int|string $expectedValue,
+ ): bool;
+
public function hasItemOnPositionWithValue(Response $response, int $position, string $key, array|string $value): bool;
public function hasItemWithTranslation(Response $response, string $locale, string $key, string $translation): bool;
diff --git a/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php b/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php
index a73e2a6415..4de59d412a 100644
--- a/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php
@@ -51,9 +51,9 @@ final class BrowsingProductVariantsContext implements Context
}
/**
- * @When I save my new configuration
+ * @When I save my new elements order
*/
- public function iSaveMyNewConfiguration(): void
+ public function iSaveMyNewElementsOrder(): void
{
$this->client->update();
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php
index 945d287759..34a29a2cd0 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php
@@ -272,13 +272,16 @@ final readonly class ManagingCatalogPromotionsContext implements Context
}
/**
- * @When I remove its every action
+ * @When I remove its last action
*/
- public function iRemoveItsEveryAction(): void
+ public function iRemoveItsLastAction(): void
{
$content = $this->client->getContent();
- $content['actions'] = [];
- $this->client->setRequestData($content);
+ $lastKey = array_key_last($content['actions']);
+ if (null !== $lastKey) {
+ unset($content['actions'][$lastKey]);
+ $this->client->setRequestData($content);
+ }
}
/**
@@ -469,15 +472,41 @@ final readonly class ManagingCatalogPromotionsContext implements Context
}
/**
- * @When I remove its every scope
+ * @When I remove its last scope
*/
- public function iRemoveItsEveryScope(): void
+ public function iRemoveItsLastScope(): void
{
$content = $this->client->getContent();
- $content['scopes'] = [];
+ $lastKey = array_key_last($content['scopes']);
+ if (null !== $lastKey) {
+ unset($content['scopes'][$lastKey]);
+ $this->client->setRequestData($content);
+ }
+ }
+
+ /**
+ * @When I add :productVariant variant to its scope
+ */
+ public function iAddVariantToItsScope(ProductVariantInterface $productVariant): void
+ {
+ $content = $this->client->getContent();
+ $content['scopes'][0]['configuration']['variants'][] = $productVariant->getCode();
$this->client->setRequestData($content);
}
+ /**
+ * @When I remove :productVariant variant from its scope
+ */
+ public function iRemoveVariantFromItsScope(ProductVariantInterface $productVariant): void
+ {
+ $content = $this->client->getContent();
+ $key = array_search($productVariant->getCode(), $content['scopes'][0]['configuration']['variants'] ?? []);
+ if (false !== $key) {
+ unset($content['scopes'][0]['configuration']['variants'][$key]);
+ $this->client->setRequestData($content);
+ }
+ }
+
/**
* @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" variant)$/
*/
@@ -485,6 +514,16 @@ final readonly class ManagingCatalogPromotionsContext implements Context
CatalogPromotionInterface $catalogPromotion,
ProductVariantInterface $productVariant,
): void {
+ $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode());
+
+ $content = $this->client->getContent();
+ unset($content['scopes'][0]);
+ $content['scopes'][0]['type'] = $type;
+ $content['scopes'][0]['configuration'] = $configuration;
+
+ $this->client->setRequestData($content);
+
+ $this->client->update();
$this->changeFirstScopeConfigurationTo(
$catalogPromotion,
InForVariantsScopeVariantChecker::TYPE,
@@ -492,34 +531,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context
);
}
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" taxon)$/
- */
- public function iEditCatalogPromotionToBeAppliedOnTaxon(
- CatalogPromotionInterface $catalogPromotion,
- TaxonInterface $taxon,
- ): void {
- $this->changeFirstScopeConfigurationTo(
- $catalogPromotion,
- InForTaxonsScopeVariantChecker::TYPE,
- ['taxons' => [$taxon->getCode()]],
- );
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" product)$/
- */
- public function iEditCatalogPromotionToBeAppliedOnProduct(
- CatalogPromotionInterface $catalogPromotion,
- ProductInterface $product,
- ): void {
- $this->changeFirstScopeConfigurationTo(
- $catalogPromotion,
- InForProductScopeVariantChecker::TYPE,
- ['products' => [$product->getCode()]],
- );
- }
-
/**
* @When I disable :catalogPromotion catalog promotion
*/
@@ -536,43 +547,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context
$this->toggleCatalogPromotion($catalogPromotion, true);
}
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to have ("[^"]+") discount$/
- */
- public function iEditCatalogPromotionToHaveDiscount(CatalogPromotionInterface $catalogPromotion, float $amount): void
- {
- $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode());
- $scopes = [[
- 'type' => PercentageDiscountPriceCalculator::TYPE,
- 'configuration' => [
- 'amount' => $amount,
- ],
- ]];
-
- $this->client->updateRequestData(['actions' => $scopes]);
- $this->client->update();
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to have ("[^"]+") of fixed discount in the ("[^"]+" channel)$/
- */
- public function iEditCatalogPromotionToHaveFixedDiscountInTheChannel(
- CatalogPromotionInterface $catalogPromotion,
- int $amount,
- ChannelInterface $channel,
- ): void {
- $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode());
- $content = $this->client->getContent();
-
- $content['actions'] = [[
- 'type' => FixedDiscountPriceCalculator::TYPE,
- 'configuration' => [$channel->getCode() => ['amount' => $amount]],
- ]];
-
- $this->client->setRequestData($content);
- $this->client->update();
- }
-
/**
* @When /^I edit it to have ("[^"]+") of fixed discount in the ("[^"]+" channel)$/
*/
@@ -1425,7 +1399,8 @@ final readonly class ManagingCatalogPromotionsContext implements Context
}
/**
- * @Then I should be notified that the fixed amount should be a number and cannot be empty
+ * @Then I should be notified that the fixed amount should be a number
+ * @Then I should be notified that the fixed amount cannot be empty
*/
public function iShouldBeNotifiedThatTheFixedAmountShouldBeANumber(): void
{
@@ -1613,23 +1588,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context
$this->sharedStorage->set('catalog_promotion', $catalogPromotion);
}
- private function changeFirstScopeConfigurationTo(
- CatalogPromotionInterface $catalogPromotion,
- string $type,
- array $configuration,
- ): void {
- $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode());
-
- $content = $this->client->getContent();
- unset($content['scopes'][0]);
- $content['scopes'][0]['type'] = $type;
- $content['scopes'][0]['configuration'] = $configuration;
-
- $this->client->setRequestData($content);
-
- $this->client->update();
- }
-
private function createCatalogPromotion(
string $name,
int $priority,
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php
index 6aa9c10f96..ff4562dea6 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php
@@ -387,7 +387,7 @@ final class ManagingCountriesContext implements Context
{
Assert::contains(
$this->responseChecker->getError($this->client->getLastResponse()),
- 'Cannot delete, the province is in use.',
+ 'Cannot delete, the Province is in use.',
);
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php
index 612b1b9ab0..5c2e3b4e43 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php
@@ -20,13 +20,14 @@ use Sylius\Behat\Context\Api\Admin\Helper\ValidationTrait;
use Sylius\Behat\Context\Api\Resources;
use Sylius\Behat\Service\Converter\SectionAwareIriConverter;
use Sylius\Behat\Service\SharedStorageInterface;
+use Sylius\Component\Core\Formatter\StringInflector;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\ChannelInterface;
-use Sylius\Component\Payment\Model\PaymentMethodInterface;
+use Sylius\Component\Core\Model\PaymentMethodInterface;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
use Webmozart\Assert\Assert;
-final class ManagingPaymentMethodsContext implements Context
+final readonly class ManagingPaymentMethodsContext implements Context
{
use ValidationTrait;
@@ -48,6 +49,43 @@ final class ManagingPaymentMethodsContext implements Context
$this->client->buildUpdateRequest(Resources::PAYMENT_METHODS, $paymentMethod->getCode());
}
+ /**
+ * @When /^I set its "Username" as "([^"]+)", "Password" as "([^"]+)" and "Signature" as "([^"]+)"$/
+ */
+ public function iSetItsUsernameAsPasswordAsAndSignatureAs(string $username, string $password, string $signature): void
+ {
+ $this->updateGatewayConfig([
+ 'username' => $username,
+ 'password' => $password,
+ 'signature' => $signature,
+ ]);
+ }
+
+ /**
+ * @When /^I set its "Publishable key" as "([^"]+)" and "Secret key" as "([^"]+)"$/
+ */
+ public function iSetItsPublishableKeyAsAndSecretKeyAs(string $publishableKey, string $secretKey): void
+ {
+ $this->updateGatewayConfig([
+ 'publishable_key' => $publishableKey,
+ 'secret_key' => $secretKey,
+ ]);
+ }
+
+ /**
+ * @When I update its :field with :value
+ */
+ public function iUpdateItsWith(string $field, string $value): void
+ {
+ $availableFields = ['Publishable key', 'Secret key', 'Username', 'Password', 'Signature', 'Sandbox'];
+
+ if (!in_array($field, $availableFields)) {
+ throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" field.', $field));
+ }
+
+ $this->updateGatewayConfig([StringInflector::nameToLowercaseCode($field) => $value]);
+ }
+
/**
* @When I name it :name in :localeCode
* @When I rename it to :name in :localeCode
@@ -58,6 +96,14 @@ final class ManagingPaymentMethodsContext implements Context
$this->client->addRequestData('translations', [$localeCode => ['name' => $name]]);
}
+ /**
+ * @When I enable sandbox mode
+ */
+ public function iEnableSandboxMode(): void
+ {
+ $this->client->addRequestData('gatewayConfig', ['config' => ['sandbox' => true]]);
+ }
+
/**
* @When I do not name it
*/
@@ -184,14 +230,6 @@ final class ManagingPaymentMethodsContext implements Context
$this->client->create();
}
- /**
- * @When I cancel my changes
- */
- public function iCancelMyChanges(): void
- {
- $this->createPage->cancelChanges();
- }
-
/**
* @When I start sorting payment methods by name
* @When the payment methods are already sorted by name
@@ -380,7 +418,7 @@ final class ManagingPaymentMethodsContext implements Context
{
$response = $this->client->index(Resources::PAYMENT_METHODS);
- if ($field = 'name') {
+ if ($field === 'Name') {
$paymentMethods = $this->responseChecker->getCollection($response);
Assert::same(end($paymentMethods)['translations']['en_US']['name'], $value);
@@ -465,9 +503,11 @@ final class ManagingPaymentMethodsContext implements Context
*/
public function iShouldBeNotifiedThatIHaveToSpecifyStripe(string $element): void
{
+ $element = strtolower($element);
+
Assert::same(
$this->responseChecker->getError($this->client->getLastResponse()),
- sprintf('gatewayConfig.config[%s]: Please enter stripe %s.', str_replace(' ', '_', strtolower($element)), $element),
+ sprintf('gatewayConfig.config[%s]: Please enter stripe %s.', str_replace(' ', '_', $element), $element),
);
}
@@ -674,13 +714,13 @@ final class ManagingPaymentMethodsContext implements Context
}
/**
- * @Then this payment method :element should be :value
+ * @Then /^this payment method "([^"]+)" should be "([^"]+)"$/
*/
public function thisPaymentMethodElementShouldBe(
string $element,
string $value,
): void {
- if ($element === 'name') {
+ if ($element === 'Name') {
Assert::inArray(
$value,
$this->getPaymentMethodNamesFromCollection(),
@@ -696,6 +736,36 @@ final class ManagingPaymentMethodsContext implements Context
);
}
+ /**
+ * @Then /^its gateway configuration "([^"]+)" should be "([^"]+)"$/
+ */
+ public function itsGatewayConfigurationShouldBe(string $element, string $value): void
+ {
+ if (!$this->sharedStorage->has('gateway_config_iri')) {
+ $this->sharedStorage->set('gateway_config_iri', $this->responseChecker->getValue($this->client->getLastResponse(), 'gatewayConfig'));
+ }
+
+ $response = $this->client->showByIri($this->sharedStorage->get('gateway_config_iri'));
+
+ Assert::true(
+ $this->responseChecker->hasValueInSubresourceObject($response, 'config', StringInflector::nameToLowercaseCode($element), $value),
+ sprintf('Gateway configuration should have %s "%s", but it does not', $element, $value),
+ );
+ }
+
+ /**
+ * @Then this payment method should be in sandbox mode
+ */
+ public function thisPaymentMethodShouldBeInSandboxMode(): void
+ {
+ $response = $this->client->showByIri($this->sharedStorage->get('gateway_config_iri'));
+
+ Assert::true(
+ $this->responseChecker->hasValueInSubresourceObject($response, 'config', 'sandbox', true),
+ 'Gateway configuration should be in sandbox mode, but it is not',
+ );
+ }
+
/**
* @Then I should be notified that it has been successfully created
*/
@@ -761,6 +831,9 @@ final class ManagingPaymentMethodsContext implements Context
return $this->responseChecker->getValue($response, 'localeCode');
}
+ /**
+ * @param array $paymentMethod
+ */
private function getFieldValueOfFirstPaymentMethod(array $paymentMethod, string $field): ?string
{
if ($field === 'code') {
@@ -774,10 +847,34 @@ final class ManagingPaymentMethodsContext implements Context
return null;
}
+ /**
+ * @return string[]
+ */
private function getPaymentMethodNamesFromCollection(): array
{
$paymentMethods = $this->responseChecker->getCollection($this->client->index(Resources::PAYMENT_METHODS));
return array_map(fn (array $paymentMethod) => $paymentMethod['translations']['en_US']['name'], $paymentMethods);
}
+
+ /**
+ * @param array $config
+ */
+ private function updateGatewayConfig(array $config): void
+ {
+ /** @var PaymentMethodInterface $paymentMethod */
+ $paymentMethod = $this->sharedStorage->get('payment_method');
+ $gatewayConfigurationIri = $this->sectionAwareIriConverter->getIriFromResourceInSection(
+ $paymentMethod->getGatewayConfig(),
+ 'admin',
+ );
+
+ $this->client->addRequestData(
+ 'gatewayConfig',
+ [
+ '@id' => $gatewayConfigurationIri,
+ 'config' => $config,
+ ],
+ );
+ }
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php
index f7166c8a36..cfab91b005 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php
@@ -320,6 +320,7 @@ final class ManagingProductsContext implements Context
* @When I set its :attribute attribute to :value
* @When I set its :attribute attribute to :value in :localeCode
* @When I do not set its :attribute attribute in :localeCode
+ * @When I set the :attribute attribute value to :value in :localeCode
*/
public function iSetItsAttributeTo(
ProductAttributeInterface $attribute,
@@ -355,6 +356,7 @@ final class ManagingProductsContext implements Context
/**
* @When I add the :attributeName attribute
+ * @When I add the :attributeName attribute to it
*/
public function iAddTheAttribute(string $attributeName): void
{
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
index 7e97d2ddfb..f96533cfa6 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php
@@ -321,25 +321,27 @@ final class ManagingPromotionsContext implements Context
}
/**
- * @When I specify that this action should be applied to items from :taxon category
+ * @When I specify that this action should be applied to items from :taxon category for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(TaxonInterface $taxon): void
- {
+ public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(
+ TaxonInterface $taxon,
+ ChannelInterface $channel,
+ ): void {
$actions = $this->getActions();
- $channelCode = key($actions[0]['configuration']);
- $actions[0]['configuration'][$channelCode]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()];
+ $actions[0]['configuration'][$channel->getCode()]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()];
$this->client->addRequestData('actions', $actions);
}
/**
- * @When I specify that this action should be applied to the :product product
+ * @When I specify that this action should be applied to the :product product for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(ProductInterface $product): void
- {
+ public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(
+ ProductInterface $product,
+ ChannelInterface $channel,
+ ): void {
$actions = $this->getActions();
- $channelCode = key($actions[0]['configuration']);
- $actions[0]['configuration'][$channelCode]['filters']['products_filter']['products'] = [$product->getCode()];
+ $actions[0]['configuration'][$channel->getCode()]['filters']['products_filter']['products'] = [$product->getCode()];
$this->client->addRequestData('actions', $actions);
}
@@ -562,6 +564,15 @@ final class ManagingPromotionsContext implements Context
);
}
+ /**
+ * @Then the :promotionName promotion should be successfully created
+ */
+ public function thePromotionShouldBeSuccessfullyCreated(string $promotionName): void
+ {
+ $this->iShouldBeNotifiedThatItHasBeenSuccessfullyCreated();
+ $this->thePromotionShouldAppearInTheRegistry($promotionName);
+ }
+
/**
* @Then I should be notified that it has been successfully created
*/
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php
index 3f0a405178..6842b6049e 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php
@@ -403,8 +403,9 @@ final class ManagingShippingMethodsContext implements Context
}
/**
- * @Then the shipping method :name should be in the registry
- * @Then the shipping method :name should appear in the registry
+ * @Then the shipping method :shippingMethod should be in the registry
+ * @Then the shipping method :shippingMethod should appear in the registry
+ * @Then the :shippingMethod shipping method should be successfully created
*/
public function theShippingMethodShouldAppearInTheRegistry(string $name): void
{
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php
index a9171d3437..9d6bd6fc53 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php
@@ -232,9 +232,9 @@ final class ManagingZonesContext implements Context
}
/**
- * @Then I can not add a zone :zone
+ * @Then /^I should not be able to add the ("[^"]+" zone) as a member$/
*/
- public function iCanNotAddAZone(ZoneInterface $zone): void
+ public function iShouldNotBeAbleToAddZoneAsAMember(ZoneInterface $zone): void
{
$this->client->addSubResourceData('members', [
'code' => $zone->getCode(),
diff --git a/src/Sylius/Behat/Context/Setup/CustomerContext.php b/src/Sylius/Behat/Context/Setup/CustomerContext.php
index fbb40b2e72..5efa3a296a 100644
--- a/src/Sylius/Behat/Context/Setup/CustomerContext.php
+++ b/src/Sylius/Behat/Context/Setup/CustomerContext.php
@@ -111,6 +111,7 @@ final class CustomerContext implements Context
/**
* @Given there is a customer :name with an email :email
+ * @Given there is also a customer :name with an email :email
*/
public function theStoreHasCustomerAccountWithEmailAndName(string $name, string $email): void
{
diff --git a/src/Sylius/Behat/Context/Setup/PaymentContext.php b/src/Sylius/Behat/Context/Setup/PaymentContext.php
index e1f89a97aa..c072b2f1b9 100644
--- a/src/Sylius/Behat/Context/Setup/PaymentContext.php
+++ b/src/Sylius/Behat/Context/Setup/PaymentContext.php
@@ -26,8 +26,14 @@ use Sylius\Component\Payment\Repository\PaymentMethodRepositoryInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Webmozart\Assert\Assert;
-final class PaymentContext implements Context
+final readonly class PaymentContext implements Context
{
+ /**
+ * @param PaymentMethodRepositoryInterface $paymentMethodRepository
+ * @param ExampleFactoryInterface $paymentMethodExampleFactory
+ * @param FactoryInterface $paymentMethodTranslationFactory
+ * @param array $gatewayFactories
+ */
public function __construct(
private SharedStorageInterface $sharedStorage,
private PaymentMethodRepositoryInterface $paymentMethodRepository,
@@ -42,7 +48,7 @@ final class PaymentContext implements Context
* @Given the store (also )allows paying (with ):paymentMethodName
* @Given the store (also )allows paying with :paymentMethodName at position :position
*/
- public function storeAllowsPaying($paymentMethodName, $position = null)
+ public function storeAllowsPaying(string $paymentMethodName, ?int $position = null): void
{
$this->createPaymentMethod($paymentMethodName, 'PM_' . StringInflector::nameToCode($paymentMethodName), 'Offline', 'Payment method', true, $position);
}
@@ -77,28 +83,32 @@ final class PaymentContext implements Context
/**
* @Given the store has (also) a payment method :paymentMethodName with a code :paymentMethodCode
*/
- public function theStoreHasAPaymentMethodWithACode($paymentMethodName, $paymentMethodCode)
+ public function theStoreHasAPaymentMethodWithACode(string $paymentMethodName, string $paymentMethodCode): void
{
$this->createPaymentMethod($paymentMethodName, $paymentMethodCode, 'Offline');
}
/**
- * @Given the store has (also) a payment method :paymentMethodName with a code :paymentMethodCode and Paypal Express Checkout gateway
+ * @Given /^the store has(?:| also) a payment method "([^"]+)" with a code "([^"]+)" and "([^"]+)" gateway$/
*/
- public function theStoreHasPaymentMethodWithCodeAndPaypalExpressCheckoutGateway(
- $paymentMethodName,
- $paymentMethodCode,
- ) {
- $paymentMethod = $this->createPaymentMethod($paymentMethodName, $paymentMethodCode, 'Paypal Express Checkout');
- $paymentMethod->getGatewayConfig()->setConfig([
- 'username' => 'TEST',
- 'password' => 'TEST',
- 'signature' => 'TEST',
- 'payum.http_client' => '@sylius.payum.http_client',
- 'sandbox' => true,
- ]);
+ public function theStoreHasPaymentMethodWithCodeAndGateway(
+ string $paymentMethodName,
+ string $paymentMethodCode,
+ string $gatewayFactory,
+ ): void {
+ $paymentMethod = $this->createPaymentMethod($paymentMethodName, $paymentMethodCode, $gatewayFactory);
+
+ match ($gatewayFactory) {
+ 'Paypal Express Checkout' => $this->configurePaypalExpressCheckoutGateway($paymentMethod),
+ 'Stripe Checkout' => $this->configureStripeCheckoutGateway($paymentMethod),
+ default => throw new \InvalidArgumentException(
+ sprintf('Gateway factory "%s" is not supported. Available options are: %s', $gatewayFactory, implode(', ', $this->gatewayFactories)),
+ ),
+ };
$this->paymentMethodManager->flush();
+
+ $this->sharedStorage->set('payment_method', $paymentMethod);
}
/**
@@ -184,24 +194,14 @@ final class PaymentContext implements Context
Assert::eq($payment->getState(), $state);
}
- /**
- * @param string $name
- * @param string $code
- * @param string $gatewayFactory
- * @param string $description
- * @param bool $addForCurrentChannel
- * @param int|null $position
- *
- * @return PaymentMethodInterface
- */
private function createPaymentMethod(
- $name,
- $code,
- $gatewayFactory = 'Offline',
- $description = '',
- $addForCurrentChannel = true,
- $position = null,
- ) {
+ string $name,
+ string $code,
+ string $gatewayFactory,
+ string $description = '',
+ bool $addForCurrentChannel = true,
+ ?int $position = null,
+ ): PaymentMethodInterface {
$gatewayFactory = array_search($gatewayFactory, $this->gatewayFactories);
/** @var PaymentMethodInterface $paymentMethod */
@@ -216,7 +216,7 @@ final class PaymentContext implements Context
]);
if (null !== $position) {
- $paymentMethod->setPosition((int) $position);
+ $paymentMethod->setPosition($position);
}
$this->sharedStorage->set('payment_method', $paymentMethod);
@@ -224,4 +224,23 @@ final class PaymentContext implements Context
return $paymentMethod;
}
+
+ private function configurePaypalExpressCheckoutGateway(PaymentMethodInterface $paymentMethod): void
+ {
+ $paymentMethod->getGatewayConfig()->setConfig([
+ 'username' => 'TEST',
+ 'password' => 'TEST',
+ 'signature' => 'TEST',
+ 'payum.http_client' => '@sylius.payum.http_client',
+ 'sandbox' => true,
+ ]);
+ }
+
+ private function configureStripeCheckoutGateway(PaymentMethodInterface $paymentMethod): void
+ {
+ $paymentMethod->getGatewayConfig()->setConfig([
+ 'publishable_key' => 'TEST',
+ 'secret_key' => 'TEST',
+ ]);
+ }
}
diff --git a/src/Sylius/Behat/Context/Transform/ProductContext.php b/src/Sylius/Behat/Context/Transform/ProductContext.php
index 8a54570486..b93118df7f 100644
--- a/src/Sylius/Behat/Context/Transform/ProductContext.php
+++ b/src/Sylius/Behat/Context/Transform/ProductContext.php
@@ -30,6 +30,8 @@ final class ProductContext implements Context
* @Transform /^"([^"]+)" product(?:|s)$/
* @Transform /^(?:a|an) "([^"]+)"$/
* @Transform :product
+ * @Transform :firstProduct
+ * @Transform :secondProduct
*/
public function getProductByName($productName)
{
diff --git a/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php b/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php
index d1cf8ce07a..64b2403467 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php
@@ -133,24 +133,24 @@ final class BrowsingProductVariantsContext implements Context
/**
* @Then /^the variant "([^"]+)" should have (\d+) items on hand$/
*/
- public function thisVariantShouldHaveItemsOnHand($productVariantName, $quantity)
+ public function thisVariantShouldHaveItemsOnHand($productVariantName, $quantity): void
{
Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
['name' => $productVariantName],
- sprintf('td > div.ui.label:contains("%s")', $quantity),
+ sprintf('[data-test-on-hand]:contains("%s")', $quantity),
));
}
/**
* @Then /^the "([^"]+)" variant of ("[^"]+" product) should have (\d+) items on hand$/
*/
- public function theVariantOfProductShouldHaveItemsOnHand($productVariantName, ProductInterface $product, $quantity)
+ public function theVariantOfProductShouldHaveItemsOnHand($productVariantName, ProductInterface $product, $quantity): void
{
$this->indexPage->open(['productId' => $product->getId()]);
Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
['name' => $productVariantName],
- sprintf('td > div.ui.label:contains("%s")', $quantity),
+ sprintf('[data-test-on-hand]:contains("%s")', $quantity),
));
}
@@ -268,10 +268,10 @@ final class BrowsingProductVariantsContext implements Context
*/
public function iShouldSeeThatTheVariantIsEnabled(ProductVariantInterface $productVariant): void
{
- Assert::true($this->indexPage->isSingleResourceOnPage([
- 'name' => $productVariant->getName(),
- 'enabled' => 'Enabled',
- ]));
+ Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
+ ['name' => $productVariant->getName()],
+ '[data-test-status-enabled]',
+ ));
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php b/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php
index 4a8358e7b4..5a0fccb2b9 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php
@@ -30,12 +30,24 @@ trait ValidationTrait
/**
* @Then I should be notified that :field is too long
- * * @Then I should be notified that :field should be no longer than :maxLength characters
+ * @Then I should be notified that :field should be no longer than :maxLength characters
*/
public function iShouldBeNotifiedThatFieldValueIsTooLong(string $field, int $maxLength = 255): void
{
+ try {
+ $validationMessage = $this
+ ->resolveCurrentPage()
+ ->getValidationMessage('field_' . StringInflector::nameToLowercaseCode($field))
+ ;
+ } catch (\InvalidArgumentException) {
+ $validationMessage = $this
+ ->resolveCurrentPage()
+ ->getValidationMessage(StringInflector::nameToLowercaseCode($field))
+ ;
+ }
+
Assert::contains(
- $this->resolveCurrentPage()->getValidationMessage(StringInflector::nameToLowercaseCode($field)),
+ $validationMessage,
sprintf('must not be longer than %d characters.', $maxLength),
);
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php
index dee4223a7c..f127fe5e38 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php
@@ -14,10 +14,12 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
+use Sylius\Behat\NotificationType;
use Sylius\Behat\Page\Admin\Administrator\ImpersonateUserPageInterface;
use Sylius\Behat\Page\Admin\Customer\ShowPageInterface;
use Sylius\Behat\Page\Admin\DashboardPageInterface;
use Sylius\Behat\Page\Shop\HomePageInterface;
+use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Component\Customer\Model\CustomerInterface;
use Webmozart\Assert\Assert;
@@ -28,6 +30,7 @@ final class ImpersonatingCustomersContext implements Context
private DashboardPageInterface $dashboardPage,
private HomePageInterface $homePage,
private ImpersonateUserPageInterface $impersonateUserPage,
+ private NotificationCheckerInterface $notificationChecker,
) {
}
@@ -123,6 +126,6 @@ final class ImpersonatingCustomersContext implements Context
*/
public function iShouldSeeThatImpersonatingWasSuccessful($email)
{
- Assert::contains($this->customerShowPage->getSuccessFlashMessage(), $email);
+ $this->notificationChecker->checkNotification($email, NotificationType::success());
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php b/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php
index 11afaeb11a..5dc4d5700c 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php
@@ -116,7 +116,7 @@ final class LoginContext implements Context
{
$this->logInAgain($username, $password);
- Assert::true($this->loginPage->hasValidationErrorWith('Error Invalid credentials.'));
+ Assert::true($this->loginPage->hasValidationErrorWith('Invalid credentials.'));
Assert::false($this->dashboardPage->isOpen());
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php
index 7bb0fbd076..b812e52862 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php
@@ -75,10 +75,11 @@ final class ManagingAdministratorsContext implements Context
/**
* @When I specify its name as :username
* @When I do not specify its name
+ * @When I change its name to :username
*/
public function iSpecifyItsNameAs($username = null): void
{
- $this->createPage->specifyUsername($username ?? '');
+ $this->createPage->setUsername($username ?? '');
}
/**
@@ -87,35 +88,20 @@ final class ManagingAdministratorsContext implements Context
public function iSpecifyItsFieldAsTooLongString(string $field): void
{
match ($field) {
- 'first name' => $this->createPage->specifyFirstName($this->getTooLongString()),
- 'last name' => $this->createPage->specifyLastName($this->getTooLongString()),
- 'username' => $this->createPage->specifyUsername($this->getTooLongString()),
+ 'first name' => $this->createPage->setFirstName($this->getTooLongString()),
+ 'last name' => $this->createPage->setLastName($this->getTooLongString()),
+ 'username' => $this->createPage->setUsername($this->getTooLongString()),
};
}
- /**
- * @When I change its name to :username
- */
- public function iChangeItsNameTo($username)
- {
- $this->updatePage->changeUsername($username);
- }
-
/**
* @When I specify its email as :email
* @When I do not specify its email
+ * @When I change its email to :email
*/
public function iSpecifyItsEmailAs($email = null)
{
- $this->createPage->specifyEmail($email ?? '');
- }
-
- /**
- * @When I change its email to :email
- */
- public function iChangeItsEmailTo($email)
- {
- $this->updatePage->changeEmail($email);
+ $this->createPage->setEmail($email ?? '');
}
/**
@@ -123,7 +109,7 @@ final class ManagingAdministratorsContext implements Context
*/
public function iSpecifyItsLocaleAs($localeCode)
{
- $this->createPage->specifyLocale($localeCode);
+ $this->createPage->setLocale($localeCode);
}
/**
@@ -131,25 +117,18 @@ final class ManagingAdministratorsContext implements Context
*/
public function iSetMyLocaleTo($localeCode)
{
- $this->updatePage->changeLocale($localeCode);
+ $this->updatePage->setLocale($localeCode);
$this->updatePage->saveChanges();
}
/**
* @When I specify its password as :password
* @When I do not specify its password
+ * @When I change its password to :password
*/
public function iSpecifyItsPasswordAs($password = null)
{
- $this->createPage->specifyPassword($password ?? '');
- }
-
- /**
- * @When I change its password to :password
- */
- public function iChangeItsPasswordTo($password)
- {
- $this->updatePage->changePassword($password);
+ $this->createPage->setPassword($password ?? '');
}
/**
@@ -264,7 +243,7 @@ final class ManagingAdministratorsContext implements Context
*/
public function iShouldBeNotifiedThatEmailMustBeUnique()
{
- Assert::same($this->createPage->getValidationMessage('email'), 'This email is already used.');
+ Assert::same($this->createPage->getValidationMessage('field_email'), 'This email is already used.');
}
/**
@@ -272,7 +251,7 @@ final class ManagingAdministratorsContext implements Context
*/
public function iShouldBeNotifiedThatNameMustBeUnique()
{
- Assert::same($this->createPage->getValidationMessage('name'), 'This username is already used.');
+ Assert::same($this->createPage->getValidationMessage('field_username'), 'This username is already used.');
}
/**
@@ -280,7 +259,7 @@ final class ManagingAdministratorsContext implements Context
*/
public function iShouldBeNotifiedThatFirstNameIsRequired($elementName)
{
- Assert::same($this->createPage->getValidationMessage($elementName), sprintf('Please enter your %s.', $elementName));
+ Assert::same($this->createPage->getValidationMessage(sprintf('%s_%s', 'field', $elementName)), sprintf('Please enter your %s.', $elementName));
}
/**
@@ -288,7 +267,7 @@ final class ManagingAdministratorsContext implements Context
*/
public function iShouldBeNotifiedThatEmailIsNotValid()
{
- Assert::same($this->createPage->getValidationMessage('email'), 'This email is invalid.');
+ Assert::same($this->createPage->getValidationMessage('field_email'), 'This email is invalid.');
}
/**
@@ -297,9 +276,9 @@ final class ManagingAdministratorsContext implements Context
public function iShouldBeNotifiedThatThisFieldIsTooLong(string $field): void
{
match ($field) {
- 'first name' => Assert::same($this->createPage->getValidationMessage('first_name'), 'First name must not be longer than 255 characters.'),
- 'last name' => Assert::same($this->createPage->getValidationMessage('last_name'), 'Last name must not be longer than 255 characters.'),
- 'username' => Assert::same($this->createPage->getValidationMessage('name'), 'Username must not be longer than 255 characters.'),
+ 'first name' => Assert::same($this->createPage->getValidationMessage('field_first_name'), 'First name must not be longer than 255 characters.'),
+ 'last name' => Assert::same($this->createPage->getValidationMessage('field_last_name'), 'Last name must not be longer than 255 characters.'),
+ 'username' => Assert::same($this->createPage->getValidationMessage('field_username'), 'Username must not be longer than 255 characters.'),
};
}
@@ -360,8 +339,8 @@ final class ManagingAdministratorsContext implements Context
{
$avatarPath = $this->sharedStorage->get($avatar);
- Assert::false($this->topBarElement->hasAvatarInMainBar($avatarPath));
- Assert::true($this->topBarElement->hasDefaultAvatarInMainBar());
+ Assert::false($this->topBarElement->hasAvatarInMainBar($avatarPath), 'Avatar should not be present in the top bar');
+ Assert::true($this->topBarElement->hasDefaultAvatarInMainBar(), 'Default avatar should be present in the top bar');
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php
index b2372fe8a1..205115868f 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php
@@ -25,6 +25,11 @@ use Sylius\Behat\Page\Admin\CatalogPromotion\UpdatePageInterface;
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Behat\Service\SharedStorageInterface;
+use Sylius\Bundle\CoreBundle\CatalogPromotion\Calculator\FixedDiscountPriceCalculator;
+use Sylius\Bundle\CoreBundle\CatalogPromotion\Calculator\PercentageDiscountPriceCalculator;
+use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForProductScopeVariantChecker;
+use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForTaxonsScopeVariantChecker;
+use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForVariantsScopeVariantChecker;
use Sylius\Component\Core\Formatter\StringInflector;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Core\Model\ChannelInterface;
@@ -38,14 +43,14 @@ final class ManagingCatalogPromotionsContext implements Context
use ValidationTrait;
public function __construct(
- private IndexPageInterface $indexPage,
- private CreatePageInterface $createPage,
- private UpdatePageInterface $updatePage,
- private ShowPageInterface $showPage,
- private FormElementInterface $formElement,
- private FilterElementInterface $filterElement,
- private SharedStorageInterface $sharedStorage,
- private NotificationCheckerInterface $notificationChecker,
+ private readonly IndexPageInterface $indexPage,
+ private readonly CreatePageInterface $createPage,
+ private readonly UpdatePageInterface $updatePage,
+ private readonly ShowPageInterface $showPage,
+ private readonly FormElementInterface $formElement,
+ private readonly FilterElementInterface $filterElement,
+ private readonly SharedStorageInterface $sharedStorage,
+ private readonly NotificationCheckerInterface $notificationChecker,
) {
}
@@ -208,7 +213,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddANewCatalogPromotionScope(): void
{
- $this->formElement->addScope();
+ $this->formElement->addScope(InForProductScopeVariantChecker::TYPE);
}
/**
@@ -220,9 +225,8 @@ final class ManagingCatalogPromotionsContext implements Context
{
$variantCodes = array_map(fn (ProductVariantInterface $variant) => $variant->getCode(), $variants);
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For variants');
- $this->formElement->chooseLastScopeCodes($variantCodes);
+ $this->formElement->addScope(InForVariantsScopeVariantChecker::TYPE);
+ $this->formElement->selectScopeOption($variantCodes);
}
/**
@@ -232,9 +236,8 @@ final class ManagingCatalogPromotionsContext implements Context
{
$taxonsCodes = array_map(fn (TaxonInterface $taxon) => $taxon->getCode(), $taxons);
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For taxons');
- $this->formElement->chooseLastScopeCodes($taxonsCodes);
+ $this->formElement->addScope(InForTaxonsScopeVariantChecker::TYPE);
+ $this->formElement->selectScopeOption($taxonsCodes);
}
/**
@@ -242,17 +245,32 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddScopeThatAppliesOnProduct(ProductInterface $product): void
{
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For product');
- $this->formElement->chooseLastScopeCodes([$product->getCode()]);
+ $this->formElement->addScope(InForProductScopeVariantChecker::TYPE);
+ $this->formElement->selectScopeOption([$product->getCode()]);
}
/**
- * @When I remove its every action
+ * @When I add :productVariant variant to its scope
*/
- public function iRemoveItsEveryAction(): void
+ public function iAddVariantToItsScope(ProductVariantInterface $productVariant): void
{
- $this->formElement->removeAllActions();
+ $this->formElement->selectScopeOption([$productVariant->getCode()]);
+ }
+
+ /**
+ * @When I remove :productVariant variant from its scope
+ */
+ public function iRemoveVariantFromItsScope(ProductVariantInterface $productVariant): void
+ {
+ $this->formElement->removeScopeOption([$productVariant->getCode()]);
+ }
+
+ /**
+ * @When I remove its last action
+ */
+ public function iRemoveItsLastAction(): void
+ {
+ $this->formElement->removeLastAction();
}
/**
@@ -260,7 +278,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddANewCatalogPromotionAction(): void
{
- $this->formElement->addAction();
+ $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE);
}
/**
@@ -269,9 +287,8 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddActionThatGivesPercentageDiscount(string $discount): void
{
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Percentage discount');
- $this->formElement->specifyLastActionDiscount($discount);
+ $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE);
+ $this->formElement->fillActionOption('Amount', $discount);
}
/**
@@ -279,9 +296,8 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddActionThatGivesFixedDiscount(string $discount, ChannelInterface $channel): void
{
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Fixed discount');
- $this->formElement->specifyLastActionDiscountForChannel($discount, $channel);
+ $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $discount);
}
/**
@@ -347,87 +363,11 @@ final class ManagingCatalogPromotionsContext implements Context
}
/**
- * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" variant)$/
+ * @When I remove its last scope
*/
- public function iEditCatalogPromotionToBeAppliedOnVariant(CatalogPromotionInterface $catalogPromotion, ProductVariantInterface $productVariant): void
+ public function iRemoveItsLastScope(): void
{
- $this->updatePage->open(['id' => $catalogPromotion->getId()]);
-
- $this->formElement->chooseLastScopeCodes([$productVariant->getCode()]);
- $this->updatePage->saveChanges();
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" taxon)$/
- */
- public function iEditCatalogPromotionToBeAppliedOnTaxon(
- CatalogPromotionInterface $catalogPromotion,
- TaxonInterface $taxon,
- ): void {
- $this->updatePage->open(['id' => $catalogPromotion->getId()]);
-
- $this->formElement->chooseScopeType('For taxons');
- $this->formElement->chooseLastScopeCodes([$taxon->getCode()]);
- $this->updatePage->saveChanges();
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" product)$/
- */
- public function iEditCatalogPromotionToBeAppliedOnProduct(
- CatalogPromotionInterface $catalogPromotion,
- ProductInterface $product,
- ): void {
- $this->updatePage->open(['id' => $catalogPromotion->getId()]);
-
- $this->formElement->chooseScopeType('For products');
- $this->formElement->chooseLastScopeCodes([$product->getCode()]);
- $this->updatePage->saveChanges();
- }
-
- /**
- * @When I remove its every scope
- */
- public function iRemoveItsEveryScope(): void
- {
- $this->formElement->removeAllScopes();
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to have "([^"]+)%" discount$/
- */
- public function iEditCatalogPromotionToHaveDiscount(CatalogPromotionInterface $catalogPromotion, string $amount): void
- {
- $this->updatePage->open(['id' => $catalogPromotion->getId()]);
- $this->formElement->specifyLastActionDiscount($amount);
- $this->updatePage->saveChanges();
- }
-
- /**
- * @When /^I edit ("[^"]+" catalog promotion) to have "(?:€|£|\$)([^"]+)" of fixed discount in the ("[^"]+" channel)$/
- */
- public function iEditCatalogPromotionToHaveFixedDiscountInTheChannel(
- CatalogPromotionInterface $catalogPromotion,
- string $discount,
- ChannelInterface $channel,
- ): void {
- $this->updatePage->open(['id' => $catalogPromotion->getId()]);
- $this->formElement->chooseActionType('Fixed discount');
- $this->formElement->specifyLastActionDiscountForChannel($discount, $channel);
- $this->updatePage->saveChanges();
-
- $this->sharedStorage->set('catalog_promotion', $catalogPromotion);
- }
-
- /**
- * @When /^I edit it to have "(?:€|£|\$)([^"]+)" of fixed discount in the ("[^"]+" channel)$/
- */
- public function iEditItToHaveFixedDiscountInTheChannel(
- string $discount,
- ChannelInterface $channel,
- ): void {
- $this->formElement->chooseActionType('Fixed discount');
- $this->formElement->specifyLastActionDiscountForChannel($discount, $channel);
+ $this->formElement->removeLastScope();
}
/**
@@ -457,7 +397,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iEditItsActionSoThatItReducesPriceBy(string $discount): void
{
- $this->formElement->specifyLastActionDiscount($discount);
+ $this->formElement->fillActionOption('Amount', $discount);
}
/**
@@ -465,8 +405,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddForVariantsScopeWithoutVariantsConfigured(): void
{
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For variants');
+ $this->formElement->addScope(InForVariantsScopeVariantChecker::TYPE);
}
/**
@@ -474,8 +413,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddForTaxonScopeWithoutTaxonsConfigured(): void
{
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For taxons');
+ $this->formElement->addScope(InForTaxonsScopeVariantChecker::TYPE);
}
/**
@@ -483,8 +421,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddCatalogPromotionScopeForProductWithoutProducts(): void
{
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For products');
+ $this->formElement->addScope(InForProductScopeVariantChecker::TYPE);
}
/**
@@ -492,8 +429,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddPercentageDiscountActionWithoutAmountConfigured(): void
{
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Percentage discount');
+ $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE);
}
/**
@@ -501,8 +437,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddFixedDiscountActionWithoutAmountConfigured(): void
{
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Fixed discount');
+ $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE);
}
/**
@@ -510,8 +445,8 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iAddInvalidPercentageDiscountActionWithNonNumberInAmount(): void
{
- $this->formElement->addAction();
- $this->formElement->specifyLastActionDiscount('alot');
+ $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE);
+ $this->formElement->fillActionOption('Amount', 'alot');
}
/**
@@ -520,9 +455,8 @@ final class ManagingCatalogPromotionsContext implements Context
public function iAddInvalidFixedDiscountActionWithNonNumberInAmountForTheChannel(
ChannelInterface $channel,
): void {
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Fixed discount');
- $this->formElement->specifyLastActionDiscountForChannel('wrong value', $channel);
+ $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', 'wrong value');
}
/**
@@ -585,8 +519,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iEditItToHaveEmptyPercentageDiscount(): void
{
- $this->formElement->chooseActionType('Percentage discount');
- $this->formElement->specifyLastActionDiscount('');
+ $this->formElement->fillActionOption('Amount', '');
}
/**
@@ -594,8 +527,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iEditItToHaveEmptyFixedDiscountInChannel(ChannelInterface $channel): void
{
- $this->formElement->chooseActionType('Fixed discount');
- $this->formElement->specifyLastActionDiscountForChannel('', $channel);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', '');
}
/**
@@ -705,7 +637,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldBeNotifiedThatADiscountAmountShouldBeBetween0And100Percent(): void
{
Assert::same(
- $this->formElement->getValidationMessage(),
+ $this->formElement->getValidationMessage('last_action'),
'The percentage discount amount must be between 0% and 100%.',
);
}
@@ -716,19 +648,30 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldBeNotifiedThatThePercentageAmountShouldBeANumber(): void
{
Assert::same(
- $this->formElement->getValidationMessage(),
+ $this->formElement->getValidationMessage('last_action'),
'The percentage discount amount must be a number and can not be empty.',
);
}
/**
- * @Then I should be notified that the fixed amount should be a number and cannot be empty
+ * @Then I should be notified that the fixed amount cannot be empty
+ */
+ public function iShouldBeNotifiedThatTheFixedAmountShouldCannotBeEmpty(): void
+ {
+ Assert::same(
+ $this->formElement->getValidationMessage('last_action'),
+ 'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.',
+ );
+ }
+
+ /**
+ * @Then I should be notified that the fixed amount should be a number
*/
public function iShouldBeNotifiedThatTheFixedAmountShouldBeANumber(): void
{
Assert::same(
- $this->formElement->getValidationMessage(),
- 'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.',
+ $this->formElement->getValidationMessage('last_action'),
+ 'Please enter a valid money amount.',
);
}
@@ -915,7 +858,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function itShouldHaveDiscount(string $amount): void
{
- Assert::same($this->formElement->getLastActionDiscount(), $amount);
+ Assert::same($this->formElement->getLastActionOption('Amount'), $amount);
}
/**
@@ -929,7 +872,7 @@ final class ManagingCatalogPromotionsContext implements Context
): void {
$this->updatePage->open(['id' => $catalogPromotion->getId()]);
- Assert::same($this->formElement->getLastActionFixedDiscount($channel), $amount);
+ Assert::same($this->formElement->getLastActionOptionForChannel($channel->getCode(), 'Amount'), $amount);
}
/**
@@ -1091,7 +1034,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iShouldBeNotifiedThatAtLeast1VariantIsRequired(): void
{
- Assert::same($this->formElement->getValidationMessage(), 'Please add at least 1 variant.');
+ Assert::same($this->formElement->getValidationMessage('last_scope'), 'Please add at least 1 variant.');
}
/**
@@ -1100,7 +1043,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldBeNotifiedThatIMustAddAtLeastOne(string $entity): void
{
Assert::same(
- $this->formElement->getValidationMessage(),
+ $this->formElement->getValidationMessage('last_scope'),
sprintf('Provided configuration contains errors. Please add at least 1 %s.', $entity),
);
}
@@ -1110,9 +1053,9 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iShouldNotBeAbleToEditItDueToWrongState(): void
{
- Assert::same(
- $this->formElement->getValidationMessage(),
+ Assert::inArray(
'The catalog promotion cannot be edited as it is currently being processed.',
+ $this->formElement->getValidationMessages(),
);
}
@@ -1186,7 +1129,7 @@ final class ManagingCatalogPromotionsContext implements Context
*/
public function iShouldGetInformationThatTheEndDateCannotBeSetBeforeStartDate(): void
{
- Assert::same($this->createPage->getValidationMessage('endDate'), 'End date cannot be set before start date.');
+ Assert::same($this->formElement->getValidationMessage('end_date_date'), 'End date cannot be set before start date.');
}
/**
@@ -1195,7 +1138,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldBeNotifiedThatNotAllChannelsAreFilled(): void
{
Assert::contains(
- $this->formElement->getValidationMessage(),
+ $this->formElement->getValidationMessage('last_action'),
'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.',
);
}
@@ -1214,7 +1157,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldSeeTheCatalogPromotionScopeConfigurationForm(): void
{
Assert::true(
- $this->createPage->checkIfScopeConfigurationFormIsVisible(),
+ $this->formElement->checkIfScopeConfigurationFormIsVisible(),
'Catalog promotion scope configuration form is not visible.',
);
}
@@ -1225,7 +1168,7 @@ final class ManagingCatalogPromotionsContext implements Context
public function iShouldSeeTheCatalogPromotionActionConfigurationForm(): void
{
Assert::true(
- $this->createPage->checkIfActionConfigurationFormIsVisible(),
+ $this->formElement->checkIfActionConfigurationFormIsVisible(),
'Catalog promotion action configuration form is not visible.',
);
}
@@ -1264,12 +1207,10 @@ final class ManagingCatalogPromotionsContext implements Context
$this->formElement->prioritizeIt($priority);
$this->formElement->setExclusiveness($exclusive);
$this->formElement->checkChannel($channel);
- $this->formElement->addScope();
- $this->formElement->chooseScopeType('For product');
- $this->formElement->chooseLastScopeCodes([$product->getCode()]);
- $this->formElement->addAction();
- $this->formElement->chooseActionType('Percentage discount');
- $this->formElement->specifyLastActionDiscount($discount);
+ $this->formElement->addScope(InForProductScopeVariantChecker::TYPE);
+ $this->formElement->selectScopeOption([$product->getCode()]);
+ $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE);
+ $this->formElement->fillActionOption('Amount', $discount);
$this->createPage->create();
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php
index f0ee23587e..f0e91c1680 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php
@@ -91,7 +91,9 @@ final class ManagingChannelsContext implements Context
*/
public function iChooseAsABaseCurrency(?CurrencyInterface $currency = null): void
{
- $this->createPage->chooseBaseCurrency($currency ? $currency->getName() : null);
+ if (null !== $currency) {
+ $this->createPage->chooseBaseCurrency($currency->getName());
+ }
}
/**
@@ -100,7 +102,9 @@ final class ManagingChannelsContext implements Context
*/
public function iChooseAsADefaultLocale(?string $defaultLocaleName = null): void
{
- $this->createPage->chooseDefaultLocale($defaultLocaleName);
+ if (null !== $defaultLocaleName) {
+ $this->createPage->chooseDefaultLocale($defaultLocaleName);
+ }
}
/**
@@ -113,18 +117,11 @@ final class ManagingChannelsContext implements Context
/**
* @When I specify menu taxon as :menuTaxon
+ * @When I change its menu taxon to :menuTaxon
*/
public function iSpecifyMenuTaxonAs(string $menuTaxon): void
{
- $this->createPage->specifyMenuTaxon($menuTaxon);
- }
-
- /**
- * @When I change its menu taxon to :menuTaxon
- */
- public function iChangeItsMenuTaxonTo(string $menuTaxon): void
- {
- $this->updatePage->changeMenuTaxon($menuTaxon);
+ $this->resolveCurrentPage()->specifyMenuTaxon($menuTaxon);
}
/**
@@ -491,7 +488,7 @@ final class ManagingChannelsContext implements Context
{
$this->updatePage->open(['id' => $channel->getId()]);
- Assert::true($this->updatePage->isLocaleChosen($nameOfLocale));
+ Assert::inArray($nameOfLocale, $this->updatePage->getLocales());
}
/**
@@ -506,13 +503,13 @@ final class ManagingChannelsContext implements Context
}
/**
- * @Then paying in :currencyCode should be possible for the :channel channel
+ * @Then paying in :currency should be possible for the :channel channel
*/
- public function payingInCurrencyShouldBePossibleForTheChannel(string $currencyCode, ChannelInterface $channel): void
+ public function payingInCurrencyShouldBePossibleForTheChannel(CurrencyInterface $currency, ChannelInterface $channel): void
{
$this->updatePage->open(['id' => $channel->getId()]);
- Assert::true($this->updatePage->isCurrencyChosen($currencyCode));
+ Assert::inArray($currency->getName(), $this->updatePage->getCurrencies());
}
/**
@@ -627,17 +624,17 @@ final class ManagingChannelsContext implements Context
{
$this->updatePage->open(['id' => $channel->getId()]);
- Assert::true($this->updatePage->isDefaultTaxZoneChosen($taxZone));
+ Assert::same($this->updatePage->getDefaultTaxZone(), $taxZone);
}
/**
- * @Given channel :channel should not have default tax zone
+ * @Then channel :channel should not have default tax zone
*/
public function channelShouldNotHaveDefaultTaxZone(ChannelInterface $channel): void
{
$this->updatePage->open(['id' => $channel->getId()]);
- Assert::false($this->updatePage->isAnyDefaultTaxZoneChosen());
+ Assert::isEmpty($this->updatePage->getDefaultTaxZone());
}
/**
@@ -649,7 +646,10 @@ final class ManagingChannelsContext implements Context
): void {
$this->updatePage->open(['id' => $channel->getId()]);
- Assert::true($this->updatePage->isTaxCalculationStrategyChosen($taxCalculationStrategy));
+ Assert::same(
+ $this->updatePage->getTaxCalculationStrategy(),
+ $taxCalculationStrategy,
+ );
}
/**
@@ -721,10 +721,10 @@ final class ManagingChannelsContext implements Context
{
$this->iWantToBrowseChannels();
- Assert::true($this->indexPage->isSingleResourceOnPage([
- 'nameAndDescription' => $channel->getName(),
- 'enabled' => $state ? 'Enabled' : 'Disabled',
- ]));
+ Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage(
+ ['nameAndDescription' => $channel->getName()],
+ $state ? '[data-test-status-enabled]' : '[data-test-status-disabled]',
+ ));
}
private function getTooLongString(): string
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php
index 734f8df69b..02702b732c 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php
@@ -57,28 +57,33 @@ final class ManagingCountriesContext implements Context
/**
* @When I choose :countryName
*/
- public function iChoose($countryName)
+ public function iChoose(string $countryName): void
{
- $this->createPage->chooseName($countryName);
+ $this->createPage->selectCountry($countryName);
}
/**
* @When I add the :provinceName province with :provinceCode code
* @When I add the :provinceName province with :provinceCode code and :provinceAbbreviation abbreviation
*/
- public function iAddProvinceWithCode($provinceName, $provinceCode, $provinceAbbreviation = null)
+ public function iAddProvinceWithCode(string $provinceName, string $provinceCode, ?string $provinceAbbreviation = null): void
{
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
- $currentPage->addProvince($provinceName, $provinceCode, $provinceAbbreviation);
+ $currentPage->addProvince();
+ $currentPage->specifyProvinceName($provinceName);
+ $currentPage->specifyProvinceCode($provinceCode);
+ if (null !== $provinceAbbreviation) {
+ $currentPage->specifyProvinceAbbreviation($provinceAbbreviation);
+ }
}
/**
* @When I add it
* @When I try to add it
*/
- public function iAddIt()
+ public function iAddIt(): void
{
$this->createPage->create();
}
@@ -94,7 +99,7 @@ final class ManagingCountriesContext implements Context
/**
* @When I disable it
*/
- public function iDisableIt()
+ public function iDisableIt(): void
{
$this->updatePage->disable();
}
@@ -131,7 +136,7 @@ final class ManagingCountriesContext implements Context
/**
* @Then /^(this country) should be disabled$/
*/
- public function thisCountryShouldBeDisabled(CountryInterface $country)
+ public function thisCountryShouldBeDisabled(CountryInterface $country): void
{
$this->indexPage->open();
@@ -141,10 +146,10 @@ final class ManagingCountriesContext implements Context
/**
* @Then I should not be able to choose :name
*/
- public function iShouldNotBeAbleToChoose($name)
+ public function iShouldNotBeAbleToChoose(string $name): void
{
try {
- $this->createPage->chooseName($name);
+ $this->createPage->selectCountry($name);
} catch (ElementNotFoundException) {
return;
}
@@ -155,7 +160,7 @@ final class ManagingCountriesContext implements Context
/**
* @Then I should not be able to edit its code
*/
- public function theCodeFieldShouldBeDisabled()
+ public function theCodeFieldShouldBeDisabled(): void
{
Assert::true($this->updatePage->isCodeFieldDisabled());
}
@@ -217,7 +222,7 @@ final class ManagingCountriesContext implements Context
/**
* @When /^I(?:| also) delete the "([^"]*)" province of this country$/
*/
- public function iDeleteTheProvinceOfCountry($provinceName)
+ public function iDeleteTheProvinceOfCountry($provinceName): void
{
$this->updatePage->removeProvince($provinceName);
}
@@ -225,27 +230,27 @@ final class ManagingCountriesContext implements Context
/**
* @When /^I want to create a new province in (country "([^"]*)")$/
*/
- public function iWantToCreateANewProvinceInCountry(CountryInterface $country)
+ public function iWantToCreateANewProvinceInCountry(CountryInterface $country): void
{
$this->updatePage->open(['id' => $country->getId()]);
- $this->updatePage->clickAddProvinceButton();
+ $this->updatePage->addProvince();
}
/**
* @When I name the province :provinceName
* @When I do not name the province
*/
- public function iNameTheProvince($provinceName = null)
+ public function iNameTheProvince($provinceName = null): void
{
- $this->updatePage->nameProvince($provinceName ?? '');
+ $this->updatePage->specifyProvinceName($provinceName ?? '');
}
/**
* @When I do not specify the province code
* @When I specify the province code as :provinceCode
*/
- public function iSpecifyTheProvinceCode($provinceCode = null)
+ public function iSpecifyTheProvinceCode($provinceCode = null): void
{
$this->updatePage->specifyProvinceCode($provinceCode ?? '');
}
@@ -315,6 +320,9 @@ final class ManagingCountriesContext implements Context
*/
public function iShouldBeNotifiedThatProvincesThatAreInUseCannotBeDeleted(): void
{
- $this->notificationChecker->checkNotification('Error Cannot delete, the province is in use.', NotificationType::failure());
+ $this->notificationChecker->checkNotification(
+ 'Error Cannot delete, the Province is in use.',
+ NotificationType::failure(),
+ );
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php
index 709783c202..ee2f152d26 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php
@@ -20,6 +20,8 @@ use Sylius\Behat\Page\Admin\Customer\IndexPageInterface as CustomerIndexPageInte
use Sylius\Behat\Page\Admin\Customer\ShowPageInterface;
use Sylius\Behat\Page\Admin\Customer\UpdatePageInterface;
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
+use Sylius\Component\Core\Formatter\StringInflector;
+use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Webmozart\Assert\Assert;
@@ -90,6 +92,15 @@ final class ManagingCustomersContext implements Context
$this->createPage->create();
}
+ /**
+ * @When I search for customer by :phrase
+ */
+ public function iSearchForCustomersWith(string $phrase): void
+ {
+ $this->indexPage->setFilterSearch($phrase);
+ $this->indexPage->filter();
+ }
+
/**
* @When I filter by group :groupName
* @When I filter by groups :firstGroup and :secondGroup
@@ -97,7 +108,7 @@ final class ManagingCustomersContext implements Context
public function iFilterByGroup(string ...$groupsNames): void
{
foreach ($groupsNames as $groupName) {
- $this->indexPage->specifyFilterGroup($groupName);
+ $this->indexPage->setFilterGroup($groupName);
}
$this->indexPage->filter();
@@ -192,7 +203,23 @@ final class ManagingCustomersContext implements Context
}
/**
- * @Then /^I should see (\d+) customers in the list$/
+ * @When /^I sort customers by (ascending|descending) registration date$/
+ */
+ public function iSortCustomersByRegistrationDate(string $order): void
+ {
+ $this->sortBy($order, 'createdAt');
+ }
+
+ /**
+ * @When /^I sort customers by (ascending|descending) (email|first name|last name)$/
+ */
+ public function iSortCustomersByField(string $order, string $field): void
+ {
+ $this->sortBy($order, StringInflector::nameToCamelCase($field));
+ }
+
+ /**
+ * @Then /^I should see (\d+) customers (?:in|on) the list$/
* @Then /^I should see a single customer on the list$/
*/
public function iShouldSeeCustomersInTheList($amountOfCustomers = 1)
@@ -202,12 +229,26 @@ final class ManagingCustomersContext implements Context
/**
* @Then I should see the customer :email in the list
+ * @Then I should see the customer :email on the list
*/
public function iShouldSeeTheCustomerInTheList($email)
{
Assert::true($this->indexPage->isSingleResourceOnPage(['email' => $email]));
}
+ /**
+ * @Then /^the (first|last) customer should be "([^"]+)"$/
+ */
+ public function theFirstLastCustomerShouldBe(string $placement, string $email): void
+ {
+ $index = 'first' === $placement ? 0 : $this->indexPage->countItems() - 1;
+
+ Assert::same(
+ $this->indexPage->getColumnFields('email')[$index],
+ $email,
+ );
+ }
+
/**
* @Then /^I should be notified that ([^"]+) is required$/
*/
@@ -435,14 +476,6 @@ final class ManagingCustomersContext implements Context
Assert::same($this->showPage->getCustomerPhoneNumber(), $phoneNumber);
}
- /**
- * @Then /^(?:their|his) default address should be "([^"]+)"$/
- */
- public function hisShippingAddressShouldBe(string $defaultAddress): void
- {
- Assert::same($this->showPage->getDefaultAddress(), str_replace(',', '', $defaultAddress));
- }
-
/**
* @Then their default address should be :firstName :lastName, :street, :postcode :city, :country
*/
@@ -456,7 +489,7 @@ final class ManagingCustomersContext implements Context
): void {
Assert::same(
$this->showPage->getDefaultAddress(),
- sprintf('%s %s %s %s %s %s', $firstName, $lastName, $street, $city, strtoupper($country), $postcode),
+ sprintf('%s %s, %s, %s %s, %s', $firstName, $lastName, $street, $postcode, $city, ucwords($country)),
);
}
@@ -465,7 +498,7 @@ final class ManagingCustomersContext implements Context
*/
public function iShouldSeeInformationAboutNoExistingAccountForThisCustomer()
{
- Assert::true($this->showPage->hasAccount());
+ Assert::false($this->showPage->hasAccount());
}
/**
@@ -645,26 +678,31 @@ final class ManagingCustomersContext implements Context
}
/**
- * @Then /^I should see that they have placed (\d+) orders? in the "([^"]+)" channel$/
+ * @Then /^I should see that they have placed (\d+) orders? in the ("[^"]+" channel)$/
*/
- public function iShouldSeeThatTheyHavePlacedOrdersInTheChannel($ordersCount, $channelName)
+ public function iShouldSeeThatTheyHavePlacedOrdersInTheChannel($ordersCount, ChannelInterface $channel)
{
- Assert::same($this->showPage->getOrdersCountInChannel($channelName), (int) $ordersCount);
+ Assert::same($this->showPage->getOrdersCountInChannel($channel->getCode()), (int) $ordersCount);
}
/**
- * @Then /^I should see that the overall total value of all their orders in the "([^"]+)" channel is "([^"]+)"$/
+ * @Then /^I should see that the overall total value of all their orders in the ("[^"]+" channel) is "([^"]+)"$/
*/
- public function iShouldSeeThatTheOverallTotalValueOfAllTheirOrdersInTheChannelIs($channelName, $ordersValue)
+ public function iShouldSeeThatTheOverallTotalValueOfAllTheirOrdersInTheChannelIs(ChannelInterface $channel, $ordersValue)
{
- Assert::same($this->showPage->getOrdersTotalInChannel($channelName), $ordersValue);
+ Assert::same($this->showPage->getOrdersTotalInChannel($channel->getCode()), $ordersValue);
}
/**
- * @Then /^I should see that the average total value of their order in the "([^"]+)" channel is "([^"]+)"$/
+ * @Then /^I should see that the average total value of their order in the ("[^"]+" channel) is "([^"]+)"$/
*/
- public function iShouldSeeThatTheAverageTotalValueOfTheirOrderInTheChannelIs($channelName, $ordersValue)
+ public function iShouldSeeThatTheAverageTotalValueOfTheirOrderInTheChannelIs(ChannelInterface $channel, $ordersValue)
{
- Assert::same($this->showPage->getOrdersTotalInChannel($channelName), $ordersValue);
+ Assert::same($this->showPage->getAverageTotalInChannel($channel->getCode()), $ordersValue);
+ }
+
+ private function sortBy(string $order, string $field): void
+ {
+ $this->indexPage->sortBy($field, str_starts_with($order, 'de') ? 'desc' : 'asc');
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php
index a13e575d01..5c9583bfb5 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php
@@ -15,7 +15,6 @@ namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
use Sylius\Behat\NotificationType;
-use Sylius\Behat\Page\Admin\Order\HistoryPageInterface;
use Sylius\Behat\Page\Admin\Order\IndexPageInterface;
use Sylius\Behat\Page\Admin\Order\ShowPageInterface;
use Sylius\Behat\Page\Admin\Order\UpdatePageInterface;
@@ -24,19 +23,19 @@ use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Behat\Service\SharedSecurityServiceInterface;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Addressing\Model\AddressInterface;
+use Sylius\Component\Addressing\Model\ProvinceInterface;
use Sylius\Component\Core\Model\AdminUserInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Webmozart\Assert\Assert;
-final class ManagingOrdersContext implements Context
+final readonly class ManagingOrdersContext implements Context
{
public function __construct(
private SharedStorageInterface $sharedStorage,
private IndexPageInterface $indexPage,
private ShowPageInterface $showPage,
private UpdatePageInterface $updatePage,
- private HistoryPageInterface $historyPage,
private ErrorPageInterface $errorPage,
private NotificationCheckerInterface $notificationChecker,
private SharedSecurityServiceInterface $sharedSecurityService,
@@ -47,24 +46,16 @@ final class ManagingOrdersContext implements Context
* @Given I am browsing orders
* @When I browse orders
*/
- public function iBrowseOrders()
+ public function iBrowseOrders(): void
{
$this->indexPage->open();
}
- /**
- * @When I browse order's :order history
- */
- public function iBrowseOrderHistory(OrderInterface $order)
- {
- $this->historyPage->open(['id' => $order->getId()]);
- }
-
/**
* @Given /^I am viewing the summary of (this order)$/
* @When I view the summary of the order :order
*/
- public function iSeeTheOrder(OrderInterface $order)
+ public function iSeeTheOrder(OrderInterface $order): void
{
$this->showPage->open(['id' => $order->getId()]);
}
@@ -80,7 +71,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I mark (this order) as paid$/
*/
- public function iMarkThisOrderAsAPaid(OrderInterface $order)
+ public function iMarkThisOrderAsAPaid(OrderInterface $order): void
{
$this->showPage->completeOrderLastPayment($order);
}
@@ -88,7 +79,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I mark (this order)'s payment as refunded$/
*/
- public function iMarkThisOrderSPaymentAsRefunded(OrderInterface $order)
+ public function iMarkThisOrderSPaymentAsRefunded(OrderInterface $order): void
{
$this->showPage->refundOrderLastPayment($order);
}
@@ -96,7 +87,7 @@ final class ManagingOrdersContext implements Context
/**
* @When specify its tracking code as :trackingCode
*/
- public function specifyItsTrackingCodeAs($trackingCode)
+ public function specifyItsTrackingCodeAs(string $trackingCode): void
{
$this->showPage->specifyTrackingCode($trackingCode);
$this->sharedStorage->set('tracking_code', $trackingCode);
@@ -105,7 +96,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I ship (this order)$/
*/
- public function iShipThisOrder(OrderInterface $order)
+ public function iShipThisOrder(OrderInterface $order): void
{
$this->showPage->shipOrder($order);
}
@@ -113,7 +104,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I switch the way orders are sorted by :fieldName
*/
- public function iSwitchSortingBy($fieldName)
+ public function iSwitchSortingBy(string $fieldName): void
{
$this->indexPage->sortBy($fieldName);
}
@@ -121,7 +112,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I specify filter date from as :dateTime
*/
- public function iSpecifyFilterDateFromAs($dateTime)
+ public function iSpecifyFilterDateFromAs(string $dateTime): void
{
$this->indexPage->specifyFilterDateFrom($dateTime);
}
@@ -129,7 +120,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I specify filter date to as :dateTime
*/
- public function iSpecifyFilterDateToAs($dateTime)
+ public function iSpecifyFilterDateToAs(string $dateTime): void
{
$this->indexPage->specifyFilterDateTo($dateTime);
}
@@ -137,7 +128,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I choose :channelName as a channel filter
*/
- public function iChooseChannelAsAChannelFilter($channelName)
+ public function iChooseChannelAsAChannelFilter(string $channelName): void
{
$this->indexPage->chooseChannelFilter($channelName);
}
@@ -145,7 +136,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I choose :methodName as a shipping method filter
*/
- public function iChooseMethodAsAShippingMethodFilter($methodName)
+ public function iChooseMethodAsAShippingMethodFilter(string $methodName): void
{
$this->indexPage->chooseShippingMethodFilter($methodName);
}
@@ -153,7 +144,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I choose :currencyName as the filter currency
*/
- public function iChooseCurrencyAsTheFilterCurrency($currencyName)
+ public function iChooseCurrencyAsTheFilterCurrency(string $currencyName): void
{
$this->indexPage->chooseCurrencyFilter($currencyName);
}
@@ -161,7 +152,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I specify filter total being greater than :total
*/
- public function iSpecifyFilterTotalBeingGreaterThan($total)
+ public function iSpecifyFilterTotalBeingGreaterThan(string $total): void
{
$this->indexPage->specifyFilterTotalGreaterThan($total);
}
@@ -169,7 +160,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I specify filter total being less than :total
*/
- public function iSpecifyFilterTotalBeingLessThan($total)
+ public function iSpecifyFilterTotalBeingLessThan(string $total): void
{
$this->indexPage->specifyFilterTotalLessThan($total);
}
@@ -177,7 +168,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I filter
*/
- public function iFilter()
+ public function iFilter(): void
{
$this->indexPage->filter();
}
@@ -224,10 +215,22 @@ final class ManagingOrdersContext implements Context
$this->showPage->resendShipmentConfirmationEmail();
}
+ /**
+ * @When I change the :addressType country to :country
+ */
+ public function iChangeTheCountryTo(string $addressType, string $country): void
+ {
+ match ($addressType) {
+ 'shipping' => $this->updatePage->changeShippingCountry($country),
+ 'billing' => $this->updatePage->changeBillingCountry($country),
+ default => throw new \InvalidArgumentException(sprintf('Address type "%s" is not supported.', $addressType)),
+ };
+ }
+
/**
* @Then I should see a single order from customer :customer
*/
- public function iShouldSeeASingleOrderFromCustomer(CustomerInterface $customer)
+ public function iShouldSeeASingleOrderFromCustomer(CustomerInterface $customer): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['customer' => $customer->getEmail()]));
}
@@ -254,7 +257,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should have been placed by the customer :customerEmail
*/
- public function itShouldBePlacedByCustomer($customerEmail)
+ public function itShouldBePlacedByCustomer(string $customerEmail): void
{
Assert::true($this->showPage->hasCustomer($customerEmail));
}
@@ -268,7 +271,7 @@ final class ManagingOrdersContext implements Context
string $postcode,
string $city,
string $countryName,
- ) {
+ ): void {
$this->itShouldBeShippedTo(null, $customerName, $street, $postcode, $city, $countryName);
}
@@ -282,7 +285,7 @@ final class ManagingOrdersContext implements Context
string $postcode,
string $city,
string $countryName,
- ) {
+ ): void {
if (null !== $order) {
$this->iSeeTheOrder($order);
}
@@ -300,7 +303,7 @@ final class ManagingOrdersContext implements Context
string $postcode,
string $city,
string $countryName,
- ) {
+ ): void {
Assert::true($this->showPage->hasBillingAddress($customerName, $street, $postcode, $city, $countryName));
}
@@ -319,6 +322,21 @@ final class ManagingOrdersContext implements Context
Assert::true($this->showPage->hasBillingAddress($customerName, $street, $postcode, $city, $countryName));
}
+ /**
+ * @Then I should be able to choose the :province province for the :addressType address
+ */
+ public function iShouldBeAbleToChooseTheProvinceForTheAddressType(ProvinceInterface $province, string $addressType): void
+ {
+ Assert::inArray(
+ $province->getName(),
+ match ($addressType) {
+ 'billing' => $this->updatePage->getAvailableProvincesForBillingAddress(),
+ 'shipping' => $this->updatePage->getAvailableProvincesForShippingAddress(),
+ default => [],
+ },
+ );
+ }
+
/**
* @Then it should have no shipping address set
*/
@@ -330,7 +348,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should be shipped via the :shippingMethodName shipping method
*/
- public function itShouldBeShippedViaShippingMethod($shippingMethodName)
+ public function itShouldBeShippedViaShippingMethod(string $shippingMethodName): void
{
Assert::true($this->showPage->hasShipment($shippingMethodName));
}
@@ -338,7 +356,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should be paid with :paymentMethodName
*/
- public function itShouldBePaidWith($paymentMethodName)
+ public function itShouldBePaidWith(string $paymentMethodName): void
{
Assert::true($this->showPage->hasPayment($paymentMethodName));
}
@@ -347,15 +365,15 @@ final class ManagingOrdersContext implements Context
* @Then /^it should have (\d+) items$/
* @Then I should see :amount orders in the list
*/
- public function itShouldHaveAmountOfItems($amount = 1)
+ public function itShouldHaveAmountOfItems(int $amount = 1): void
{
- Assert::same($this->showPage->countItems(), (int) $amount);
+ Assert::same($this->showPage->countItems(), $amount);
}
/**
* @Then the product named :productName should be in the items list
*/
- public function theProductShouldBeInTheItemsList($productName)
+ public function theProductShouldBeInTheItemsList(string $productName): void
{
Assert::true($this->showPage->isProductInTheList($productName));
}
@@ -363,7 +381,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the order's items total should be :itemsTotal
*/
- public function theOrdersItemsTotalShouldBe($itemsTotal)
+ public function theOrdersItemsTotalShouldBe(string $itemsTotal): void
{
Assert::eq($this->showPage->getItemsTotal(), $itemsTotal);
}
@@ -371,7 +389,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^the order's total should(?:| still) be "([^"]+)"$/
*/
- public function theOrdersTotalShouldBe($total)
+ public function theOrdersTotalShouldBe(string $total): void
{
Assert::eq($this->showPage->getTotal(), $total);
}
@@ -395,7 +413,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the order's shipping total should be :shippingTotal
*/
- public function theOrdersShippingTotalShouldBe($shippingTotal)
+ public function theOrdersShippingTotalShouldBe(string $shippingTotal): void
{
Assert::eq($this->showPage->getShippingTotal(), $shippingTotal);
}
@@ -403,7 +421,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the order's payment should (also) be :paymentAmount
*/
- public function theOrdersPaymentShouldBe($paymentAmount)
+ public function theOrdersPaymentShouldBe(string $paymentAmount): void
{
Assert::eq($this->showPage->getPaymentAmount(), $paymentAmount);
}
@@ -411,7 +429,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the order should have tax :tax
*/
- public function theOrderShouldHaveTax($tax)
+ public function theOrderShouldHaveTax(string $tax): void
{
Assert::true($this->showPage->hasTax($tax));
}
@@ -419,7 +437,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^the order's tax total should(?:| still) be "([^"]+)"$/
*/
- public function theOrdersTaxTotalShouldBe($taxTotal)
+ public function theOrdersTaxTotalShouldBe(string $taxTotal): void
{
Assert::eq($this->showPage->getTaxTotal(), $taxTotal);
}
@@ -435,7 +453,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the order's shipping promotion should be :promotion
*/
- public function theOrdersShippingPromotionDiscountShouldBe($promotionData)
+ public function theOrdersShippingPromotionDiscountShouldBe(string $promotionData): void
{
Assert::same($this->showPage->getShippingPromotionData(), $promotionData);
}
@@ -443,7 +461,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^the order's promotion total should(?:| still) be "([^"]+)"$/
*/
- public function theOrdersPromotionTotalShouldBe($promotionTotal)
+ public function theOrdersPromotionTotalShouldBe(string $promotionTotal): void
{
Assert::same($this->showPage->getOrderPromotionTotal(), $promotionTotal);
}
@@ -451,7 +469,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I check :itemName data
*/
- public function iCheckData($itemName)
+ public function iCheckData(string $itemName): void
{
$this->sharedStorage->set('item', $itemName);
}
@@ -459,7 +477,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) code should be "([^"]+)"$/
*/
- public function itemCodeShouldBe($itemName, $code)
+ public function itemCodeShouldBe(string $itemName, string $code): void
{
Assert::same($this->showPage->getItemCode($itemName), $code);
}
@@ -467,7 +485,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) unit price should be ([^"]+)$/
*/
- public function itemUnitPriceShouldBe($itemName, $unitPrice)
+ public function itemUnitPriceShouldBe(string $itemName, int $unitPrice): void
{
Assert::eq($this->showPage->getItemUnitPrice($itemName), $unitPrice);
}
@@ -475,7 +493,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) discounted unit price should be ([^"]+)$/
*/
- public function itemDiscountedUnitPriceShouldBe($itemName, $discountedUnitPrice)
+ public function itemDiscountedUnitPriceShouldBe(string $itemName, int $discountedUnitPrice): void
{
Assert::eq($this->showPage->getItemDiscountedUnitPrice($itemName), $discountedUnitPrice);
}
@@ -483,7 +501,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) quantity should be ([^"]+)$/
*/
- public function itemQuantityShouldBe($itemName, $quantity)
+ public function itemQuantityShouldBe(string $itemName, int $quantity): void
{
Assert::eq($this->showPage->getItemQuantity($itemName), $quantity);
}
@@ -491,7 +509,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) subtotal should be ([^"]+)$/
*/
- public function itemSubtotalShouldBe($itemName, $subtotal)
+ public function itemSubtotalShouldBe(string $itemName, int $subtotal): void
{
Assert::eq($this->showPage->getItemSubtotal($itemName), $subtotal);
}
@@ -499,7 +517,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) discount should be ([^"]+)$/
*/
- public function theItemShouldHaveDiscount($itemName, $discount)
+ public function theItemShouldHaveDiscount(string $itemName, int $discount): void
{
Assert::eq($this->showPage->getItemDiscount($itemName), $discount);
}
@@ -507,7 +525,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) tax should be ([^"]+)$/
*/
- public function itemTaxShouldBe($itemName, $tax)
+ public function itemTaxShouldBe(string $itemName, int $tax): void
{
Assert::eq($this->showPage->getItemTax($itemName), $tax);
}
@@ -523,7 +541,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(its) total should be ([^"]+)$/
*/
- public function itemTotalShouldBe($itemName, $total)
+ public function itemTotalShouldBe(string $itemName, int $total): void
{
Assert::eq($this->showPage->getItemTotal($itemName), $total);
}
@@ -531,7 +549,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should be notified that the order's payment has been successfully completed
*/
- public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyCompleted()
+ public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyCompleted(): void
{
$this->notificationChecker->checkNotification(
'Payment has been successfully updated.',
@@ -542,7 +560,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should be notified that the order's payment could not be finalized due to insufficient stock
*/
- public function iShouldBeNotifiedThatTheOrderSPaymentCouldNotBeFinalizedDueToInsufficientStock()
+ public function iShouldBeNotifiedThatTheOrderSPaymentCouldNotBeFinalizedDueToInsufficientStock(): void
{
$this->notificationChecker->checkNotification(
'The payment cannot be completed due to insufficient stock of the',
@@ -553,7 +571,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should be notified that the order's payment has been successfully refunded
*/
- public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyRefunded()
+ public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyRefunded(): void
{
$this->notificationChecker->checkNotification(
'Payment has been successfully refunded.',
@@ -565,7 +583,7 @@ final class ManagingOrdersContext implements Context
* @Then it should have payment state :paymentState
* @Then it should have payment with state :paymentState
*/
- public function itShouldHavePaymentState($paymentState)
+ public function itShouldHavePaymentState(string $paymentState): void
{
Assert::true($this->showPage->hasPayment($paymentState));
}
@@ -573,7 +591,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should have order's payment state :orderPaymentState
*/
- public function itShouldHaveOrderPaymentState($orderPaymentState)
+ public function itShouldHaveOrderPaymentState(string $orderPaymentState): void
{
Assert::same($this->showPage->getPaymentState(), $orderPaymentState);
}
@@ -581,7 +599,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should have order's shipping state :orderShippingState
*/
- public function itShouldHaveOrderShippingState($orderShippingState)
+ public function itShouldHaveOrderShippingState(string $orderShippingState): void
{
Assert::same($this->showPage->getShippingState(), $orderShippingState);
}
@@ -589,7 +607,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it's payment state should be refunded
*/
- public function orderPaymentStateShouldBeRefunded()
+ public function orderPaymentStateShouldBeRefunded(): void
{
Assert::same($this->showPage->getPaymentState(), 'Refunded');
}
@@ -597,7 +615,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^I should not be able to mark (this order) as paid again$/
*/
- public function iShouldNotBeAbleToFinalizeItsPayment(OrderInterface $order)
+ public function iShouldNotBeAbleToFinalizeItsPayment(OrderInterface $order): void
{
Assert::false($this->showPage->canCompleteOrderLastPayment($order));
}
@@ -605,10 +623,10 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should be notified that the order has been successfully shipped
*/
- public function iShouldBeNotifiedThatTheOrderHasBeenSuccessfullyShipped()
+ public function iShouldBeNotifiedThatTheOrderHasBeenSuccessfullyShipped(): void
{
$this->notificationChecker->checkNotification(
- 'Shipment has been successfully updated.',
+ 'Shipment has been successfully shipped.',
NotificationType::success(),
);
}
@@ -616,7 +634,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^I should not be able to ship (this order)$/
*/
- public function iShouldNotBeAbleToShipThisOrder(OrderInterface $order)
+ public function iShouldNotBeAbleToShipThisOrder(OrderInterface $order): void
{
Assert::false($this->showPage->canShipOrder($order));
}
@@ -624,7 +642,7 @@ final class ManagingOrdersContext implements Context
/**
* @When I cancel this order
*/
- public function iCancelThisOrder()
+ public function iCancelThisOrder(): void
{
$this->showPage->cancelOrder();
}
@@ -632,7 +650,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should be notified that it has been successfully updated
*/
- public function iShouldBeNotifiedAboutItHasBeenSuccessfullyCanceled()
+ public function iShouldBeNotifiedAboutItHasBeenSuccessfullyCanceled(): void
{
$this->notificationChecker->checkNotification(
'Order has been successfully updated.',
@@ -643,7 +661,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should not be able to cancel this order
*/
- public function iShouldNotBeAbleToCancelThisOrder()
+ public function iShouldNotBeAbleToCancelThisOrder(): void
{
Assert::false($this->showPage->hasCancelButton());
}
@@ -652,7 +670,7 @@ final class ManagingOrdersContext implements Context
* @Then this order should have state :state
* @Then its state should be :state
*/
- public function itsStateShouldBe($state)
+ public function itsStateShouldBe(string $state): void
{
Assert::same($this->showPage->getOrderState(), $state);
}
@@ -660,7 +678,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should( still) have a :state state
*/
- public function itShouldHaveState($state)
+ public function itShouldHaveState(string $state): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['state' => $state]));
}
@@ -670,9 +688,9 @@ final class ManagingOrdersContext implements Context
*/
public function theCustomerServiceShouldKnowAboutThisAdditionalNotes(
AdminUserInterface $user,
- $note,
+ string $note,
OrderInterface $order,
- ) {
+ ): void {
$this->sharedSecurityService->performActionAsAdminUser(
$user,
function () use ($note, $order) {
@@ -686,7 +704,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should see an order with :orderNumber number
*/
- public function iShouldSeeOrderWithNumber($orderNumber)
+ public function iShouldSeeOrderWithNumber(string $orderNumber): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['number' => $orderNumber]));
}
@@ -694,7 +712,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should not see an order with :orderNumber number
*/
- public function iShouldNotSeeOrderWithNumber($orderNumber)
+ public function iShouldNotSeeOrderWithNumber(string $orderNumber): void
{
Assert::false($this->indexPage->isSingleResourceOnPage(['number' => $orderNumber]));
}
@@ -702,7 +720,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should not see any orders with currency :currencyCode
*/
- public function iShouldNotSeeAnyOrderWithCurrency($currencyCode)
+ public function iShouldNotSeeAnyOrderWithCurrency(string $currencyCode): void
{
Assert::false($this->indexPage->isSingleResourceOnPage(['currencyCode' => $currencyCode]));
}
@@ -710,7 +728,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then the first order should have number :number
*/
- public function theFirstOrderShouldHaveNumber($number)
+ public function theFirstOrderShouldHaveNumber(string $number): void
{
Assert::eq($this->indexPage->getColumnFields('number')[0], $number);
}
@@ -718,15 +736,15 @@ final class ManagingOrdersContext implements Context
/**
* @Then it should have shipment in state :shipmentState
*/
- public function itShouldHaveShipmentState($shipmentState)
+ public function itShouldHaveShipmentState(string $shipmentState): void
{
- Assert::true($this->showPage->hasShipment($shipmentState));
+ Assert::true($this->showPage->hasShipmentWithState($shipmentState));
}
/**
* @Then order :orderNumber should have shipment state :shippingState
*/
- public function thisOrderShipmentStateShouldBe($shippingState)
+ public function thisOrderShipmentStateShouldBe(string $shippingState): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['shippingState' => $shippingState]));
}
@@ -735,7 +753,7 @@ final class ManagingOrdersContext implements Context
* @Then the order :order should have order payment state :orderPaymentState
* @Then /^(this order) should have order payment state "([^"]+)"$/
*/
- public function theOrderShouldHavePaymentState(OrderInterface $order, $orderPaymentState)
+ public function theOrderShouldHavePaymentState(OrderInterface $order, string $orderPaymentState): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['paymentState' => $orderPaymentState]));
}
@@ -744,7 +762,7 @@ final class ManagingOrdersContext implements Context
* @Then the order :order should have order shipping state :orderShippingState
* @Then /^(this order) should have order shipping state "([^"]+)"$/
*/
- public function theOrderShouldHaveShippingState(OrderInterface $order, $orderShippingState)
+ public function theOrderShouldHaveShippingState(OrderInterface $order, string $orderShippingState): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['shippingState' => $orderShippingState]));
}
@@ -752,7 +770,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^there should be(?:| only) (\d+) payments?$/
*/
- public function theOrderShouldHaveNumberOfPayments($number)
+ public function theOrderShouldHaveNumberOfPayments(string $number): void
{
Assert::same($this->showPage->getPaymentsCount(), (int) $number);
}
@@ -760,7 +778,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should see the order :orderNumber with total :total
*/
- public function iShouldSeeTheOrderWithTotal($orderNumber, $total)
+ public function iShouldSeeTheOrderWithTotal(string $orderNumber, int $total): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['total' => $total]));
}
@@ -768,7 +786,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I want to modify a customer's (?:billing|shipping) address of (this order)$/
*/
- public function iWantToModifyACustomerSShippingAddress(OrderInterface $order)
+ public function iWantToModifyACustomerSShippingAddress(OrderInterface $order): void
{
$this->updatePage->open(['id' => $order->getId()]);
}
@@ -777,7 +795,7 @@ final class ManagingOrdersContext implements Context
* @When I save my changes
* @When I try to save my changes
*/
- public function iSaveMyChanges()
+ public function iSaveMyChanges(): void
{
$this->updatePage->saveChanges();
}
@@ -785,7 +803,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I specify their (?:|new )shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
*/
- public function iSpecifyTheirShippingAddressAsFor(AddressInterface $address)
+ public function iSpecifyTheirShippingAddressAsFor(AddressInterface $address): void
{
$this->updatePage->specifyShippingAddress($address);
}
@@ -793,7 +811,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I specify their (?:|new )billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
*/
- public function iSpecifyTheirBillingAddressAsFor(AddressInterface $address)
+ public function iSpecifyTheirBillingAddressAsFor(AddressInterface $address): void
{
$this->updatePage->specifyBillingAddress($address);
}
@@ -820,7 +838,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should see :provinceName as province in the shipping address
*/
- public function iShouldSeeAsProvinceInTheShippingAddress($provinceName)
+ public function iShouldSeeAsProvinceInTheShippingAddress(string $provinceName): void
{
Assert::true($this->showPage->hasShippingProvinceName($provinceName));
}
@@ -828,7 +846,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then I should see :provinceName as province in the billing address
*/
- public function iShouldSeeAdProvinceInTheBillingAddress($provinceName)
+ public function iShouldSeeAdProvinceInTheBillingAddress(string $provinceName): void
{
Assert::true($this->showPage->hasBillingProvinceName($provinceName));
}
@@ -839,7 +857,7 @@ final class ManagingOrdersContext implements Context
public function theAdministratorShouldKnowAboutIPAddressOfThisOrderMadeBy(
AdminUserInterface $user,
OrderInterface $order,
- ) {
+ ): void {
$this->sharedSecurityService->performActionAsAdminUser(
$user,
function () use ($order) {
@@ -853,7 +871,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I (clear the billing address) information$/
*/
- public function iClearTheBillingAddressInformation(AddressInterface $address)
+ public function iClearTheBillingAddressInformation(AddressInterface $address): void
{
$this->updatePage->specifyBillingAddress($address);
}
@@ -861,7 +879,7 @@ final class ManagingOrdersContext implements Context
/**
* @When /^I (clear the shipping address) information$/
*/
- public function iClearTheShippingAddressInformation(AddressInterface $address)
+ public function iClearTheShippingAddressInformation(AddressInterface $address): void
{
$this->updatePage->specifyShippingAddress($address);
}
@@ -877,8 +895,11 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(the administrator) should see that (order placed by "[^"]+") has "([^"]+)" currency$/
*/
- public function theAdministratorShouldSeeThatThisOrderHasBeenPlacedIn(AdminUserInterface $user, OrderInterface $order, $currency)
- {
+ public function theAdministratorShouldSeeThatThisOrderHasBeenPlacedIn(
+ AdminUserInterface $user,
+ OrderInterface $order,
+ string $currency,
+ ): void {
$this->sharedSecurityService->performActionAsAdminUser($user, function () use ($order, $currency) {
$this->showPage->open(['id' => $order->getId()]);
@@ -889,7 +910,7 @@ final class ManagingOrdersContext implements Context
/**
* @Then /^(the administrator) should see the order with total "([^"]+)" in order list$/
*/
- public function theAdministratorShouldSeeTheOrderWithTotalInOrderList(AdminUserInterface $user, $total)
+ public function theAdministratorShouldSeeTheOrderWithTotalInOrderList(AdminUserInterface $user, int $total): void
{
$this->sharedSecurityService->performActionAsAdminUser($user, function () use ($total) {
$this->indexPage->open();
@@ -898,26 +919,10 @@ final class ManagingOrdersContext implements Context
});
}
- /**
- * @Then there should be :count shipping address changes in the registry
- */
- public function thereShouldBeCountShippingAddressChangesInTheRegistry(int $count): void
- {
- Assert::same($this->historyPage->countShippingAddressChanges(), $count);
- }
-
- /**
- * @Then there should be :count billing address changes in the registry
- */
- public function thereShouldBeCountBillingAddressChangesInTheRegistry(int $count): void
- {
- Assert::same($this->historyPage->countBillingAddressChanges(), $count);
- }
-
/**
* @Then I should not be able to refund this payment
*/
- public function iShouldNotBeAbleToRefundThisPayment()
+ public function iShouldNotBeAbleToRefundThisPayment(): void
{
Assert::false($this->showPage->hasRefundButton());
}
@@ -1032,7 +1037,7 @@ final class ManagingOrdersContext implements Context
*
* @throws \InvalidArgumentException
*/
- private function assertElementValidationMessage($type, $element, $expectedMessage)
+ private function assertElementValidationMessage(string $type, string $element, string $expectedMessage): void
{
$element = sprintf('%s_%s', $type, str_replace(' ', '_', $element));
Assert::true($this->updatePage->checkValidationMessageFor($element, $expectedMessage));
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php
index 531d3e778f..d525ad5579 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php
@@ -14,26 +14,29 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
+use Behat\Mink\Exception\ElementNotFoundException;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
use Sylius\Behat\Page\Admin\PaymentMethod\CreatePageInterface;
use Sylius\Behat\Page\Admin\PaymentMethod\UpdatePageInterface;
-use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
+use Sylius\Component\Core\Formatter\StringInflector;
use Sylius\Component\Payment\Model\PaymentMethodInterface;
use Webmozart\Assert\Assert;
-final class ManagingPaymentMethodsContext implements Context
+final readonly class ManagingPaymentMethodsContext implements Context
{
use ValidationTrait;
+ /**
+ * @param string[] $gatewayFactories
+ */
public function __construct(
private CreatePageInterface $createPage,
private IndexPageInterface $indexPage,
private UpdatePageInterface $updatePage,
private CurrentPageResolverInterface $currentPageResolver,
- private NotificationCheckerInterface $notificationChecker,
private array $gatewayFactories,
) {
}
@@ -59,10 +62,64 @@ final class ManagingPaymentMethodsContext implements Context
$currentPage->nameIt($name ?? '', $language);
}
+ /**
+ * @When I update its :field with :value
+ */
+ public function iUpdateItsWith(string $field, string $value): void
+ {
+ match ($field) {
+ 'Publishable key' => $this->updatePage->setStripePublishableKey($value),
+ 'Secret key' => $this->updatePage->setStripeSecretKey($value),
+ 'Username' => $this->updatePage->setPaypalGatewayUsername($value),
+ 'Password' => $this->updatePage->setPaypalGatewayPassword($value),
+ 'Signature' => $this->updatePage->setPaypalGatewaySignature($value),
+ default => throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" field.', $field)),
+ };
+ }
+
+ /**
+ * @When I configure it with( only) :element
+ */
+ public function iConfigureItWith(string $element): void
+ {
+ match ($element) {
+ 'Publishable key' => $this->createPage->setStripePublishableKey('TEST'),
+ 'Secret key' => $this->createPage->setStripeSecretKey('TEST'),
+ default => throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" element.', $element)),
+ };
+ }
+
+ /**
+ * @When /^I set its "Username" as "([^"]+)", "Password" as "([^"]+)" and "Signature" as "([^"]+)"$/
+ */
+ public function iSetItsUsernameAsPasswordAsAndSignatureAs(string $username, string $password, string $signature): void
+ {
+ $this->updatePage->setPaypalGatewayUsername($username);
+ $this->updatePage->setPaypalGatewayPassword($password);
+ $this->updatePage->setPaypalGatewaySignature($signature);
+ }
+
+ /**
+ * @When /^I set its "Publishable key" as "([^"]+)" and "Secret key" as "([^"]+)"$/
+ */
+ public function iSetItsPublishableKeyAsAndSecretKeyAs(string $publishableKey, string $secretKey): void
+ {
+ $this->updatePage->setStripePublishableKey($publishableKey);
+ $this->updatePage->setStripeSecretKey($secretKey);
+ }
+
+ /**
+ * @When I enable sandbox mode
+ */
+ public function iEnableSandboxMode(): void
+ {
+ $this->updatePage->enableSandboxMode();
+ }
+
/**
* @When I do not name it
*/
- public function iDoNotNameIt()
+ public function iDoNotNameIt(): void
{
// Intentionally left blank to fulfill context expectation
}
@@ -70,7 +127,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I enable it
*/
- public function iEnableIt()
+ public function iEnableIt(): void
{
$this->updatePage->enable();
}
@@ -78,7 +135,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I disable it
*/
- public function iDisableIt()
+ public function iDisableIt(): void
{
$this->updatePage->disable();
}
@@ -87,7 +144,7 @@ final class ManagingPaymentMethodsContext implements Context
* @When I save my changes
* @When I try to save my changes
*/
- public function iSaveMyChanges()
+ public function iSaveMyChanges(): void
{
$this->updatePage->saveChanges();
}
@@ -96,25 +153,36 @@ final class ManagingPaymentMethodsContext implements Context
* @When I delete the :paymentMethod payment method
* @When I try to delete the :paymentMethod payment method
*/
- public function iDeletePaymentMethod(PaymentMethodInterface $paymentMethod)
+ public function iDeletePaymentMethod(PaymentMethodInterface $paymentMethod): void
{
$this->indexPage->open();
$this->indexPage->deleteResourceOnPage(['code' => $paymentMethod->getCode(), 'name' => $paymentMethod->getName()]);
}
/**
- * @Then this payment method :element should be :value
+ * @Then /^(?:this payment method|its gateway configuration) "([^"]+)" should be "([^"]+)"$/
*/
- public function thisPaymentMethodElementShouldBe($element, $value)
+ public function itsGatewayConfigurationShouldBe(string $element, string $value): void
{
- Assert::true($this->updatePage->hasResourceValues([$element => $value]));
+ Assert::true(
+ $this->updatePage->hasResourceValues([StringInflector::nameToLowercaseCode($element) => $value]),
+ sprintf('Expected "%s" to be "%s", but it is not.', StringInflector::nameToLowercaseCode($element), $value),
+ );
+ }
+
+ /**
+ * @Then this payment method should be in sandbox mode
+ */
+ public function thisPaymentMethodShouldBeInSandboxMode(): void
+ {
+ Assert::true($this->updatePage->isPaymentMethodInSandboxMode());
}
/**
* @When I want to create a new offline payment method
* @When I want to create a new payment method with :factory gateway factory
*/
- public function iWantToCreateANewPaymentMethod($factory = 'Offline')
+ public function iWantToCreateANewPaymentMethod(string $factory = 'Offline'): void
{
$this->createPage->open(['factory' => array_search($factory, $this->gatewayFactories, true)]);
}
@@ -131,7 +199,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I describe it as :description in :language
*/
- public function iDescribeItAsIn($description, $language)
+ public function iDescribeItAsIn(string $description, string $language): void
{
$this->createPage->describeIt($description, $language);
}
@@ -139,7 +207,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When make it available in channel :channel
*/
- public function iMakeItAvailableInChannel($channel)
+ public function iMakeItAvailableInChannel(string $channel): void
{
$this->createPage->checkChannel($channel);
}
@@ -147,7 +215,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Given I set its instruction as :instructions in :language
*/
- public function iSetItsInstructionAsIn($instructions, $language)
+ public function iSetItsInstructionAsIn(string $instructions, string $language): void
{
$this->createPage->setInstructions($instructions, $language);
}
@@ -155,8 +223,10 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I add it
* @When I try to add it
+ *
+ * @throws ElementNotFoundException
*/
- public function iAddIt()
+ public function iAddIt(): void
{
$this->createPage->create();
}
@@ -200,7 +270,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Given /^(this payment method) should still be in the registry$/
*/
- public function thisPaymentMethodShouldStillBeInTheRegistry(PaymentMethodInterface $paymentMethod)
+ public function thisPaymentMethodShouldStillBeInTheRegistry(PaymentMethodInterface $paymentMethod): void
{
$this->thePaymentMethodShouldAppearInTheRegistry($paymentMethod->getName());
}
@@ -209,7 +279,7 @@ final class ManagingPaymentMethodsContext implements Context
* @Given I am browsing payment methods
* @When I browse payment methods
*/
- public function iBrowsePaymentMethods()
+ public function iBrowsePaymentMethods(): void
{
$this->indexPage->open();
}
@@ -233,7 +303,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then the first payment method on the list should have :field :value
*/
- public function theFirstPaymentMethodOnTheListShouldHave($field, $value)
+ public function theFirstPaymentMethodOnTheListShouldHave(string $field, string $value): void
{
Assert::same($this->indexPage->getColumnFields($field)[0], $value);
}
@@ -241,7 +311,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then the last payment method on the list should have :field :value
*/
- public function theLastPaymentMethodOnTheListShouldHave($field, $value)
+ public function theLastPaymentMethodOnTheListShouldHave(string $field, string $value): void
{
$values = $this->indexPage->getColumnFields($field);
@@ -254,7 +324,7 @@ final class ManagingPaymentMethodsContext implements Context
* @When I switch the way payment methods are sorted to descending by :field
* @Given the payment methods are already sorted by :field
*/
- public function iSortPaymentMethodsBy($field)
+ public function iSortPaymentMethodsBy(string $field): void
{
$this->indexPage->sortBy($field);
}
@@ -271,16 +341,20 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then I should be notified that :element is required
* @Then I should be notified that I have to specify payment method :element
+ *
+ * @throws ElementNotFoundException
*/
- public function iShouldBeNotifiedThatIsRequired($element)
+ public function iShouldBeNotifiedThatIsRequired(string $element): void
{
$this->assertFieldValidationMessage($element, sprintf('Please enter payment method %s.', $element));
}
/**
* @Then I should be notified that I have to specify paypal :element
+ *
+ * @throws ElementNotFoundException
*/
- public function iShouldBeNotifiedThatIHaveToSpecifyPaypal($element)
+ public function iShouldBeNotifiedThatIHaveToSpecifyPaypal(string $element): void
{
Assert::same(
$this->createPage->getValidationMessage('paypal_' . $element),
@@ -290,19 +364,23 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then I should be notified that I have to specify stripe :element
+ *
+ * @throws ElementNotFoundException
*/
public function iShouldBeNotifiedThatIHaveToSpecifyStripe(string $element): void
{
Assert::same(
- $this->createPage->getValidationMessage('stripe_' . str_replace(' ', '_', $element)),
- sprintf('Please enter stripe %s.', $element),
+ $this->createPage->getValidationMessage('stripe_' . str_replace(' ', '_', strtolower($element))),
+ sprintf('Please enter stripe %s.', strtolower($element)),
);
}
/**
* @Then I should be notified that gateway name should contain only letters and underscores
+ *
+ * @throws ElementNotFoundException
*/
- public function iShouldBeNotifiedThatGatewayNameShouldContainOnlyLettersAndUnderscores()
+ public function iShouldBeNotifiedThatGatewayNameShouldContainOnlyLettersAndUnderscores(): void
{
Assert::same(
$this->createPage->getValidationMessage('gateway_name'),
@@ -313,7 +391,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then the payment method with :element :value should not be added
*/
- public function thePaymentMethodWithElementValueShouldNotBeAdded($element, $value)
+ public function thePaymentMethodWithElementValueShouldNotBeAdded(string $element, string $value): void
{
$this->iBrowsePaymentMethods();
@@ -323,7 +401,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then /^(this payment method) should still be named "([^"]+)"$/
*/
- public function thisShippingMethodNameShouldBe(PaymentMethodInterface $paymentMethod, $paymentMethodName)
+ public function thisShippingMethodNameShouldBe(PaymentMethodInterface $paymentMethod, string $paymentMethodName): void
{
$this->iBrowsePaymentMethods();
@@ -334,10 +412,9 @@ final class ManagingPaymentMethodsContext implements Context
}
/**
- * @param string $element
- * @param string $expectedMessage
+ * @throws ElementNotFoundException
*/
- private function assertFieldValidationMessage($element, $expectedMessage)
+ private function assertFieldValidationMessage(string $element, string $expectedMessage): void
{
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
@@ -349,7 +426,7 @@ final class ManagingPaymentMethodsContext implements Context
* @Then the code field should be disabled
* @Then I should not be able to edit its code
*/
- public function theCodeFieldShouldBeDisabled()
+ public function theCodeFieldShouldBeDisabled(): void
{
Assert::true($this->updatePage->isCodeDisabled());
}
@@ -357,7 +434,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then the factory name field should be disabled
*/
- public function theFactoryNameFieldShouldBeDisabled()
+ public function theFactoryNameFieldShouldBeDisabled(): void
{
Assert::true($this->updatePage->isFactoryNameFieldDisabled());
}
@@ -365,7 +442,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then this payment method should be enabled
*/
- public function thisPaymentMethodShouldBeEnabled()
+ public function thisPaymentMethodShouldBeEnabled(): void
{
Assert::true($this->updatePage->isPaymentMethodEnabled());
}
@@ -373,7 +450,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then this payment method should be disabled
*/
- public function thisPaymentMethodShouldBeDisabled()
+ public function thisPaymentMethodShouldBeDisabled(): void
{
Assert::false($this->updatePage->isPaymentMethodEnabled());
}
@@ -383,9 +460,9 @@ final class ManagingPaymentMethodsContext implements Context
*/
public function thePaymentMethodShouldHaveInstructionsIn(
PaymentMethodInterface $paymentMethod,
- $instructions,
- $language,
- ) {
+ string $instructions,
+ string $language,
+ ): void {
$this->iWantToModifyAPaymentMethod($paymentMethod);
Assert::same($this->updatePage->getPaymentMethodInstructions($language), $instructions);
@@ -396,8 +473,8 @@ final class ManagingPaymentMethodsContext implements Context
*/
public function thePaymentMethodShouldBeAvailableInChannel(
PaymentMethodInterface $paymentMethod,
- $channelName,
- ) {
+ string $channelName,
+ ): void {
$this->iWantToModifyAPaymentMethod($paymentMethod);
Assert::true($this->updatePage->isAvailableInChannel($channelName));
@@ -406,7 +483,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then /^(this payment method) should no longer exist in the registry$/
*/
- public function thisPaymentMethodShouldNoLongerExistInTheRegistry(PaymentMethodInterface $paymentMethod)
+ public function thisPaymentMethodShouldNoLongerExistInTheRegistry(PaymentMethodInterface $paymentMethod): void
{
Assert::false($this->indexPage->isSingleResourceOnPage([
'code' => $paymentMethod->getCode(),
@@ -416,8 +493,10 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then I should be notified that payment method with this code already exists
+ *
+ * @throws ElementNotFoundException
*/
- public function iShouldBeNotifiedThatPaymentMethodWithThisCodeAlreadyExists()
+ public function iShouldBeNotifiedThatPaymentMethodWithThisCodeAlreadyExists(): void
{
Assert::same($this->createPage->getValidationMessage('code'), 'The payment method with given code already exists.');
}
@@ -425,7 +504,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @Then there should still be only one payment method with :element :code
*/
- public function thereShouldStillBeOnlyOnePaymentMethodWith($element, $code)
+ public function thereShouldStillBeOnlyOnePaymentMethodWith(string $element, string $code): void
{
$this->iBrowsePaymentMethods();
@@ -435,7 +514,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I configure it with test paypal credentials
*/
- public function iConfigureItWithTestPaypalCredentials()
+ public function iConfigureItWithTestPaypalCredentials(): void
{
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
@@ -448,7 +527,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I configure it for username :username with :signature signature
*/
- public function iConfigureItForUsernameWithSignature($username, $signature)
+ public function iConfigureItForUsernameWithSignature(string $username, string $signature): void
{
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
@@ -460,7 +539,7 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I do not specify configuration password
*/
- public function iDoNotSpecifyConfigurationPassword()
+ public function iDoNotSpecifyConfigurationPassword(): void
{
// Intentionally left blank to fulfill context expectation
}
@@ -468,23 +547,12 @@ final class ManagingPaymentMethodsContext implements Context
/**
* @When I configure it with test stripe gateway data
*/
- public function iConfigureItWithTestStripeGatewayData()
+ public function iConfigureItWithTestStripeGatewayData(): void
{
$this->createPage->setStripeSecretKey('TEST');
$this->createPage->setStripePublishableKey('TEST');
}
- /**
- * @When I configure it with only :element
- */
- public function iConfigureItWithOnly(string $element): void
- {
- match ($element) {
- 'publishable key' => $this->createPage->setStripePublishableKey('TEST'),
- 'secret key' => $this->createPage->setStripeSecretKey('TEST'),
- };
- }
-
/**
* @Then I should be redirected to the previous page of only enabled payment methods
*/
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php
index 4266942e52..5b3fe73038 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php
@@ -155,4 +155,17 @@ final class ManagingPaymentsContext implements Context
{
Assert::true($this->indexPage->isPaymentWithOrderNumberInPosition($orderNumber, $position));
}
+
+ /**
+ * @When /^I sort payments by date in (ascending|descending) order$/
+ */
+ public function iSortPaymentsByRegistrationDate(string $order): void
+ {
+ $this->sortBy($order, 'createdAt');
+ }
+
+ private function sortBy(string $order, string $field): void
+ {
+ $this->indexPage->sortBy($field, str_starts_with($order, 'de') ? 'desc' : 'asc');
+ }
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php
index 392837973e..7ab8c43a49 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php
@@ -14,10 +14,12 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
-use Sylius\Behat\Page\Admin\ProductAssociationType\CreatePageInterface;
+use Sylius\Behat\Element\Admin\ProductAssociationType\FormElementInterface;
+use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
+use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
use Sylius\Behat\Page\Admin\ProductAssociationType\IndexPageInterface;
-use Sylius\Behat\Page\Admin\ProductAssociationType\UpdatePageInterface;
-use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
+use Sylius\Behat\Service\SharedStorageInterface;
+use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
use Webmozart\Assert\Assert;
@@ -27,7 +29,8 @@ final class ManagingProductAssociationTypesContext implements Context
private CreatePageInterface $createPage,
private IndexPageInterface $indexPage,
private UpdatePageInterface $updatePage,
- private CurrentPageResolverInterface $currentPageResolver,
+ private FormElementInterface $formElement,
+ private SharedStorageInterface $sharedStorage,
) {
}
@@ -61,7 +64,7 @@ final class ManagingProductAssociationTypesContext implements Context
*/
public function iNameItIn($name, $language)
{
- $this->createPage->nameItIn($name, $language);
+ $this->formElement->setName($name, $language);
}
/**
@@ -76,18 +79,18 @@ final class ManagingProductAssociationTypesContext implements Context
* @When I rename it to :name in :language
* @When I remove its name from :language translation
*/
- public function iRenameItToInLanguage(string $language, ?string $name = null): void
+ public function iRenameItToInLanguage(string $language, string $name = ''): void
{
- $this->updatePage->nameItIn($name ?? '', $language);
+ $this->formElement->setName($name, $language);
}
/**
* @When I specify its code as :code
* @When I do not specify its code
*/
- public function iSpecifyItsCodeAs($code = null)
+ public function iSpecifyItsCodeAs(string $code = '')
{
- $this->createPage->specifyCode($code ?? '');
+ $this->formElement->setCode($code);
}
/**
@@ -199,7 +202,7 @@ final class ManagingProductAssociationTypesContext implements Context
*/
public function iShouldNotBeAbleToEditItsCode(): void
{
- Assert::true($this->updatePage->isCodeDisabled());
+ Assert::true($this->formElement->isCodeDisabled());
}
/**
@@ -220,7 +223,7 @@ final class ManagingProductAssociationTypesContext implements Context
public function iShouldBeNotifiedThatProductAssociationTypeWithThisCodeAlreadyExists()
{
Assert::same(
- $this->createPage->getValidationMessage('code'),
+ $this->formElement->getValidationMessage('code'),
'The association type with given code already exists.',
);
}
@@ -240,7 +243,13 @@ final class ManagingProductAssociationTypesContext implements Context
*/
public function iShouldBeNotifiedThatIsRequired($element)
{
- $this->assertFieldValidationMessage($element, sprintf('Please enter association type %s.', $element));
+ /** @var LocaleInterface $locale */
+ $locale = $this->sharedStorage->get('locale');
+
+ Assert::same(
+ $this->formElement->getValidationMessage($element, ['%locale%' => $locale->getCode()]),
+ sprintf('Please enter association type %s.', $element),
+ );
}
/**
@@ -252,16 +261,4 @@ final class ManagingProductAssociationTypesContext implements Context
Assert::false($this->indexPage->isSingleResourceOnPage([$element => $value]));
}
-
- /**
- * @param string $element
- * @param string $expectedMessage
- */
- private function assertFieldValidationMessage($element, $expectedMessage)
- {
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
- }
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php
index 4adfbec4f1..ecb9f85494 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php
@@ -220,15 +220,15 @@ final class ManagingProductVariantsContext implements Context
/**
* @When I set the position of :name to :position
*/
- public function iSetThePositionOfTo($name, int $position)
+ public function iSetThePositionOfTo(string $name, int $position): void
{
$this->indexPage->setPosition($name, $position);
}
/**
- * @When I save my new configuration
+ * @When I save my new elements order
*/
- public function iSaveMyNewConfiguration()
+ public function iSaveMyNewElementsOrder(): void
{
$this->indexPage->savePositions();
}
@@ -320,7 +320,7 @@ final class ManagingProductVariantsContext implements Context
ChannelInterface $channel,
): void {
$this->generatePage->specifyCode($nthVariant - 1, $code);
- $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel);
+ $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel->getCode());
}
/**
@@ -336,7 +336,7 @@ final class ManagingProductVariantsContext implements Context
*/
public function iSpecifyThereAreVariantsWithCost(int $nthVariant, int $price, ChannelInterface $channel): void
{
- $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel);
+ $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel->getCode());
}
/**
@@ -565,10 +565,10 @@ final class ManagingProductVariantsContext implements Context
/**
* @Then /^I should be notified that prices in all channels must be defined for the (\d)(?:st|nd|rd|th) variant$/
*/
- public function iShouldBeNotifiedThatPricesInAllChannelsMustBeDefinedForTheVariant($position)
+ public function iShouldBeNotifiedThatPricesInAllChannelsMustBeDefinedForTheVariant($position): void
{
Assert::same(
- $this->generatePage->getPricesValidationMessage($position - 1),
+ $this->generatePage->getValidationMessage('channel_pricings', $position - 1),
'You must define price for every enabled channel.',
);
}
@@ -751,6 +751,22 @@ final class ManagingProductVariantsContext implements Context
Assert::true($this->updatePage->isSelectedOptionValueOnPage($optionName, $optionValue));
}
+ /**
+ * @Then /^I should not be able to remove (\d)(?:st|nd|rd|th) product variant$/
+ */
+ public function iShouldNotBeAbleToRemove(int $nthVariant): void
+ {
+ Assert::false($this->generatePage->isProductVariantRemovable($nthVariant - 1));
+ }
+
+ /**
+ * @Then /^I should be able to remove (\d)(?:st|nd|rd|th) product variant$/
+ */
+ public function iShouldBeAbleToRemove(int $nthVariant): void
+ {
+ Assert::true($this->generatePage->isProductVariantRemovable($nthVariant - 1));
+ }
+
/**
* @param string $element
* @param string $message
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php
index 7a0b612136..8f7099fbb5 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php
@@ -579,14 +579,23 @@ final class ManagingProductsContext implements Context
$this->createConfigurableProductPage->selectOption($optionName);
}
+ /**
+ * @When I add the :attributeName attribute
+ * @When I add the :attributeName attribute to it
+ */
+ public function iAddTheAttribute(string $attributeName): void
+ {
+ $this->createSimpleProductPage->addAttribute($attributeName);
+ }
+
/**
* @When I set its :attributeName attribute to :value in :localeCode
* @When I do not set its :attributeName attribute in :localeCode
- * @When I add the :attributeName attribute
+ * @When I set the :attributeName attribute value to :value in :localeCode
*/
public function iSetItsAttributeTo(string $attributeName, ?string $value = null, $localeCode = 'en_US'): void
{
- $this->createSimpleProductPage->addAttribute($attributeName, $value ?? '', $localeCode);
+ $this->createSimpleProductPage->updateAttribute($attributeName, $value ?? '', $localeCode);
}
/**
@@ -594,7 +603,7 @@ final class ManagingProductsContext implements Context
*/
public function iSelectValueInLanguageForTheAttribute(string $value, string $language, string $attribute): void
{
- $this->createSimpleProductPage->selectAttributeValue($attribute, $value, $language);
+ $this->createSimpleProductPage->updateAttribute($attribute, $value, $language);
}
/**
@@ -602,7 +611,7 @@ final class ManagingProductsContext implements Context
*/
public function iSelectValueForTheAttribute(string $value, string $attribute): void
{
- $this->createSimpleProductPage->selectAttributeValue($attribute, $value, '');
+ $this->createSimpleProductPage->updateAttribute($attribute, $value, '');
}
/**
@@ -610,7 +619,7 @@ final class ManagingProductsContext implements Context
*/
public function iSetItsNonTranslatableAttributeTo(string $attributeName, string $value): void
{
- $this->createSimpleProductPage->addNonTranslatableAttribute($attributeName, $value);
+ $this->createSimpleProductPage->updateAttribute($attributeName, $value, '');
}
/**
@@ -661,7 +670,7 @@ final class ManagingProductsContext implements Context
): void {
$this->updateSimpleProductPage->open(['id' => $product->getId()]);
- Assert::same($this->updateSimpleProductPage->getAttributeSelectText($attributeName, $localeCode), $value);
+ Assert::same($this->updateSimpleProductPage->getAttributeValue($attributeName, $localeCode), $value);
}
/**
@@ -671,7 +680,7 @@ final class ManagingProductsContext implements Context
{
$this->updateSimpleProductPage->open(['id' => $product->getId()]);
- Assert::same($this->updateSimpleProductPage->getNonTranslatableAttributeValue($attributeName), $value);
+ Assert::same($this->updateSimpleProductPage->getAttributeValue($attributeName, ''), $value);
}
/**
@@ -895,15 +904,15 @@ final class ManagingProductsContext implements Context
}
/**
- * @When I remove an associated product :productName from :productAssociationType
+ * @When I remove an associated product :product from :productAssociationType
*/
public function iRemoveAnAssociatedProductFromProductAssociation(
- $productName,
+ ProductInterface $product,
ProductAssociationTypeInterface $productAssociationType,
) {
$currentPage = $this->resolveCurrentPage();
- $currentPage->removeAssociatedProduct($productName, $productAssociationType);
+ $currentPage->removeAssociatedProduct($product, $productAssociationType);
}
/**
@@ -937,7 +946,7 @@ final class ManagingProductsContext implements Context
{
$currentPage = $this->resolveCurrentPage();
- Assert::true($currentPage->isImageWithTypeDisplayed($type));
+ Assert::true($currentPage->hasImageWithType($type));
}
/**
@@ -963,7 +972,7 @@ final class ManagingProductsContext implements Context
{
$currentPage = $this->resolveCurrentPage();
- Assert::false($currentPage->isImageWithTypeDisplayed($code));
+ Assert::false($currentPage->hasImageWithType($code));
}
/**
@@ -1041,33 +1050,45 @@ final class ManagingProductsContext implements Context
}
/**
- * @Then this product should( also) have an association :productAssociationType with product :productName
- * @Then this product should( also) have an association :productAssociationType with products :firstProductName and :secondProductName
+ * @Then this product should( also) have an association :productAssociationType with product :product
*/
- public function theProductShouldHaveAnAssociationWithProducts(
+ public function theProductShouldHaveAnAssociationWithProduct(
ProductAssociationTypeInterface $productAssociationType,
- ...$productsNames,
+ ProductInterface $product,
) {
- foreach ($productsNames as $productName) {
- Assert::true(
- $this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType),
- sprintf(
- 'This product should have an association %s with product %s.',
- $productAssociationType->getName(),
- $productName,
- ),
- );
+ Assert::true(
+ $this->updateSimpleProductPage->hasAssociatedProduct($product, $productAssociationType),
+ sprintf(
+ 'This product should have an association %s with product %s.',
+ $productAssociationType->getName(),
+ $product->getName(),
+ ),
+ );
+ }
+
+ /**
+ * @Then /^this product should have an (association "[^"]+") with (products "[^"]+" and "[^"]+")$/
+ * @Then /^this product should also have an (association "[^"]+") with (products "[^"]+" and "[^"]+")$/
+ *
+ * @param array $products
+ */
+ public function theProductsShouldHaveAnAssociationWithProducts(
+ ProductAssociationTypeInterface $productAssociationType,
+ array $products,
+ ): void {
+ foreach ($products as $product) {
+ $this->theProductShouldHaveAnAssociationWithProduct($productAssociationType, $product);
}
}
/**
- * @Then this product should not have an association :productAssociationType with product :productName
+ * @Then this product should not have an association :productAssociationType with product :product
*/
public function theProductShouldNotHaveAnAssociationWithProduct(
ProductAssociationTypeInterface $productAssociationType,
- $productName,
- ) {
- Assert::false($this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType));
+ ProductInterface $product,
+ ): void {
+ Assert::false($this->updateSimpleProductPage->hasAssociatedProduct($product, $productAssociationType));
}
/**
@@ -1267,7 +1288,7 @@ final class ManagingProductsContext implements Context
*/
public function iShouldSeeInventoryOfThisProduct(): void
{
- Assert::true($this->updateSimpleProductPage->hasInventoryTab());
+ Assert::true($this->updateSimpleProductPage->hasTab('inventory'));
}
/**
@@ -1275,7 +1296,7 @@ final class ManagingProductsContext implements Context
*/
public function iShouldNotSeeInventoryOfThisProduct(): void
{
- Assert::false($this->updateConfigurableProductPage->hasInventoryTab());
+ Assert::false($this->updateConfigurableProductPage->hasTab('inventory'));
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
index 54b92f6736..496b4e8541 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php
@@ -27,6 +27,16 @@ use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\PromotionInterface;
+use Sylius\Component\Core\Promotion\Action\FixedDiscountPromotionActionCommand;
+use Sylius\Component\Core\Promotion\Action\PercentageDiscountPromotionActionCommand;
+use Sylius\Component\Core\Promotion\Action\UnitFixedDiscountPromotionActionCommand;
+use Sylius\Component\Core\Promotion\Action\UnitPercentageDiscountPromotionActionCommand;
+use Sylius\Component\Core\Promotion\Checker\Rule\CartQuantityRuleChecker;
+use Sylius\Component\Core\Promotion\Checker\Rule\ContainsProductRuleChecker;
+use Sylius\Component\Core\Promotion\Checker\Rule\CustomerGroupRuleChecker;
+use Sylius\Component\Core\Promotion\Checker\Rule\HasTaxonRuleChecker;
+use Sylius\Component\Core\Promotion\Checker\Rule\ItemTotalRuleChecker;
+use Sylius\Component\Core\Promotion\Checker\Rule\TotalOfItemsFromTaxonRuleChecker;
use Webmozart\Assert\Assert;
final class ManagingPromotionsContext implements Context
@@ -58,7 +68,7 @@ final class ManagingPromotionsContext implements Context
* @When I want to browse promotions
* @When I browse promotions
*/
- public function iWantToBrowsePromotions()
+ public function iWantToBrowsePromotions(): void
{
$this->indexPage->open();
}
@@ -88,7 +98,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iRemoveItsPriority(?int $priority = null): void
{
- $this->formElement->prioritizeIt($priority);
+ $this->formElement->setPriority($priority);
}
/**
@@ -118,7 +128,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iSpecifyItsLabelInLocaleCode(string $label, string $localeCode): void
{
- $this->createPage->specifyLabel($label, $localeCode);
+ $this->formElement->setLabel($label, $localeCode);
}
/**
@@ -126,7 +136,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iSpecifyItsLabelWithAStringExceedingTheLimitInLocale(string $localeCode): void
{
- $this->createPage->specifyLabel(str_repeat('a', 256), $localeCode);
+ $this->formElement->setLabel(str_repeat('a', 256), $localeCode);
}
/**
@@ -135,7 +145,7 @@ final class ManagingPromotionsContext implements Context
public function thePromotionShouldHaveLabelInLocale(PromotionInterface $promotion, string $label, string $localeCode): void
{
$this->updatePage->open(['id' => $promotion->getId()]);
- $this->createPage->hasLabel($label, $localeCode);
+ $this->formElement->hasLabel($label, $localeCode);
}
/**
@@ -144,19 +154,19 @@ final class ManagingPromotionsContext implements Context
*/
public function iAddTheHasTaxonRuleConfiguredWith(string ...$taxons): void
{
- $this->createPage->addRule('Has at least one from taxons');
+ $this->formElement->addRule(HasTaxonRuleChecker::TYPE);
- $this->createPage->selectAutocompleteRuleOption('Taxons', $taxons, true);
+ $this->formElement->selectAutocompleteRuleOptions($taxons);
}
/**
* @When /^I add the "Total price of items from taxon" rule configured with "([^"]+)" taxon and "(?:€|£|\$)([^"]+)" amount for ("[^"]+" channel)$/
*/
- public function iAddTheRuleConfiguredWith($taxonName, $amount, ChannelInterface $channel)
+ public function iAddTheRuleConfiguredWith(string $taxonName, $amount, ChannelInterface $channel): void
{
- $this->createPage->addRule('Total price of items from taxon');
- $this->createPage->selectAutocompleteRuleOption('Taxon', $taxonName);
- $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->addRule(TotalOfItemsFromTaxonRuleChecker::TYPE);
+ $this->formElement->selectAutocompleteRuleOptions([$taxonName], $channel->getCode());
+ $this->formElement->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -168,18 +178,27 @@ final class ManagingPromotionsContext implements Context
$secondAmount,
ChannelInterface $secondChannel,
) {
- $this->createPage->addRule('Item total');
- $this->createPage->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount);
- $this->createPage->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount);
+ $this->formElement->addRule(ItemTotalRuleChecker::TYPE);
+ $this->formElement->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount);
+ $this->formElement->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount);
}
/**
- * @When /^I add the "([^"]+)" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/
+ * @When /^I add the "Order fixed discount" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/
*/
- public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount, ChannelInterface $channel)
+ public function iAddTheOrderFixedDiscountActionConfiguredWithAmountForChannel($amount, ChannelInterface $channel): void
{
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->addAction(FixedDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
+ }
+
+ /**
+ * @When /^I add the "Item fixed discount" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/
+ */
+ public function iAddTheItemFixedDiscountActionConfiguredWithAmountForChannel($amount, ChannelInterface $channel): void
+ {
+ $this->formElement->addAction(UnitFixedDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -187,7 +206,7 @@ final class ManagingPromotionsContext implements Context
*/
public function itIsConfiguredWithAmountForChannel($amount, ChannelInterface $channel)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount);
}
/**
@@ -195,7 +214,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iAddAMinPriceFilterRangeForChannel(ChannelInterface $channel, $minimum)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum);
}
/**
@@ -203,7 +222,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iAddAMaxPriceFilterRangeForChannel(ChannelInterface $channel, $maximum)
{
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum);
}
/**
@@ -216,44 +235,73 @@ final class ManagingPromotionsContext implements Context
}
/**
- * @When I specify that this action should be applied to items from :taxonName category
+ * @When I specify that this action should be applied to items from :taxonName category for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
+ public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(string $taxonName, ChannelInterface $channel): void
{
- $this->createPage->selectAutoCompleteFilterOption('Taxons', $taxonName);
+ $this->formElement->selectAutocompleteActionFilterOptions([$taxonName], $channel->getCode(), 'taxons');
}
/**
- * @When /^I add the "([^"]+)" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/
+ * @When /^I add the "Item percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/
*/
- public function iAddTheActionConfiguredWithAPercentageValueForChannel(
- string $actionType,
+ public function iAddTheItemPercentageDiscountActionConfiguredWithAPercentageValueForChannel(
string $percentage,
ChannelInterface $channel,
): void {
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage);
+ $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage);
}
/**
- * @When I add the :actionType action configured without a percentage value for :channel channel
+ * @When /^I add the "Order percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/
*/
- public function iAddTheActionConfiguredWithoutAPercentageValueForChannel(
- string $actionType,
+ public function iAddTheOrderPercentageDiscountActionConfiguredWithAPercentageValueForChannel(
+ string $percentage,
ChannelInterface $channel,
): void {
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', '');
+ $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage);
}
/**
- * @When /^I add the "([^"]+)" action configured with a percentage value of "(?:|-)([^"]+)%"$/
- * @When I add the :actionType action configured without a percentage value
+ * @When I add the "Order percentage discount" action configured without a percentage value for :channel channel
*/
- public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null)
+ public function iAddTheOrderPercentageDiscountActionConfiguredWithoutAPercentageValueForChannel(
+ ChannelInterface $channel,
+ ): void {
+ $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', '');
+ }
+
+ /**
+ * @When I add the "Item percentage discount" action configured without a percentage value for :channel channel
+ */
+ public function iAddTheItemPercentageDiscountActionConfiguredWithoutAPercentageValueForChannel(
+ ChannelInterface $channel,
+ ): void {
+ $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', '');
+ }
+
+ /**
+ * @When /^I add the "Order percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%"$/
+ * @When I add the "Order percentage discount" action configured without a percentage value
+ */
+ public function iAddTheOrderPercentageDiscountActionConfiguredWithAPercentageValue($percentage = null)
{
- $this->createPage->addAction($actionType);
- $this->createPage->fillActionOption('Percentage', $percentage ?? '');
+ $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOption('Percentage', $percentage ?? '');
+ }
+
+ /**
+ * @When /^I add the "Item percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%"$/
+ * @When I add the "Item percentage discount" action configured without a percentage value
+ */
+ public function iAddTheItemPercentageDiscountActionConfiguredWithAPercentageValue($percentage = null)
+ {
+ $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE);
+ $this->formElement->fillActionOption('Percentage', $percentage ?? '');
}
/**
@@ -261,8 +309,8 @@ final class ManagingPromotionsContext implements Context
*/
public function iAddTheCustomerGroupRuleConfiguredForGroup($customerGroupName)
{
- $this->createPage->addRule('Customer group');
- $this->createPage->selectRuleOption('Customer group', $customerGroupName);
+ $this->formElement->addRule(CustomerGroupRuleChecker::TYPE);
+ $this->formElement->selectRuleOption('Customer group', $customerGroupName);
}
/**
@@ -273,6 +321,22 @@ final class ManagingPromotionsContext implements Context
$this->indexPage->checkResourceOnPage(['name' => $promotionName]);
}
+ /**
+ * @When I remove its last rule
+ */
+ public function iRemoveItsLastRule(): void
+ {
+ $this->formElement->removeLastRule();
+ }
+
+ /**
+ * @When I remove its last action
+ */
+ public function iRemoveItsLastAction(): void
+ {
+ $this->formElement->removeLastAction();
+ }
+
/**
* @When I delete them
*/
@@ -354,7 +418,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
{
- Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.');
+ Assert::same($this->formElement->getValidationMessage('code'), 'The promotion with given code already exists.');
}
/**
@@ -380,18 +444,15 @@ final class ManagingPromotionsContext implements Context
/**
* @When I set its usage limit to :usageLimit
*/
- public function iSetItsUsageLimitTo($usageLimit)
+ public function iSetItsUsageLimitTo(int $usageLimit): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->fillUsageLimit($usageLimit);
+ $this->formElement->setUsageLimit($usageLimit);
}
/**
* @Then the :promotion promotion should be available to be used only :usageLimit times
*/
- public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
+ public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, int $usageLimit): void
{
$this->iWantToModifyAPromotion($promotion);
@@ -403,10 +464,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iSetItAsExclusive(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->makeExclusive();
+ $this->formElement->makeExclusive();
}
/**
@@ -414,16 +472,13 @@ final class ManagingPromotionsContext implements Context
*/
public function iSetItAsNotAppliesToDiscountedByCatalogPromotionItems(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->makeNotAppliesToDiscountedItem();
+ $this->formElement->makeNotAppliesToDiscountedItem();
}
/**
* @Then the :promotion promotion should be exclusive
*/
- public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
+ public function thePromotionShouldBeExclusive(PromotionInterface $promotion): void
{
$this->assertIfFieldIsTrue($promotion, 'exclusive');
}
@@ -439,18 +494,15 @@ final class ManagingPromotionsContext implements Context
/**
* @When I make it coupon based
*/
- public function iMakeItCouponBased()
+ public function iMakeItCouponBased(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->checkCouponBased();
+ $this->formElement->makeCouponBased();
}
/**
* @Then the :promotion promotion should be coupon based
*/
- public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
+ public function thePromotionShouldBeCouponBased(PromotionInterface $promotion): void
{
$this->assertIfFieldIsTrue($promotion, 'coupon_based');
}
@@ -458,18 +510,15 @@ final class ManagingPromotionsContext implements Context
/**
* @When I make it applicable for the :channelName channel
*/
- public function iMakeItApplicableForTheChannel($channelName)
+ public function iMakeItApplicableForTheChannel(string $channelName): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->checkChannel($channelName);
+ $this->formElement->checkChannel($channelName);
}
/**
* @Then the :promotion promotion should be applicable for the :channelName channel
*/
- public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName)
+ public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, string $channelName): void
{
$this->iWantToModifyAPromotion($promotion);
@@ -549,13 +598,10 @@ final class ManagingPromotionsContext implements Context
/**
* @When I make it available from :startsDate to :endsDate
*/
- public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate)
+ public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- $currentPage->setStartsAt($startsDate);
- $currentPage->setEndsAt($endsDate);
+ $this->formElement->setStartsAt($startsDate);
+ $this->formElement->setEndsAt($endsDate);
}
/**
@@ -566,7 +612,6 @@ final class ManagingPromotionsContext implements Context
$this->iWantToModifyAPromotion($promotion);
Assert::true($this->updatePage->hasStartsAt($startsDate));
-
Assert::true($this->updatePage->hasEndsAt($endsDate));
}
@@ -575,19 +620,16 @@ final class ManagingPromotionsContext implements Context
*/
public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStarts(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.');
+ Assert::same($this->formElement->getValidationMessage('ends_at_date'), 'End date cannot be set prior start date.');
}
/**
* @Then I should be notified that this value should not be blank
*/
- public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
+ public function iShouldBeNotifiedThatThisValueShouldNotBeBlank(): void
{
Assert::same(
- $this->createPage->getValidationMessageForAction(),
+ $this->formElement->getValidationMessageForAction(),
'This value should not be blank.',
);
}
@@ -600,7 +642,7 @@ final class ManagingPromotionsContext implements Context
public function iShouldBeNotifiedThatPercentageDiscountShouldBeBetween(): void
{
Assert::same(
- $this->createPage->getValidationMessageForAction(),
+ $this->formElement->getValidationMessageForAction(),
'The percentage discount must be between 0% and 100%.',
);
}
@@ -621,18 +663,18 @@ final class ManagingPromotionsContext implements Context
/**
* @When I add the "Contains product" rule configured with the :productName product
*/
- public function iAddTheRuleConfiguredWithTheProduct($productName)
+ public function iAddTheRuleConfiguredWithTheProduct(string $productName): void
{
- $this->createPage->addRule('Contains product');
- $this->createPage->selectAutocompleteRuleOption('Product code', $productName);
+ $this->formElement->addRule(ContainsProductRuleChecker::TYPE);
+ $this->formElement->selectAutocompleteRuleOptions([$productName]);
}
/**
- * @When I specify that this action should be applied to the :productName product
+ * @When I specify that this action should be applied to the :productName product for :channel channel
*/
- public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
+ public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(string $productName, ChannelInterface $channel): void
{
- $this->createPage->selectAutoCompleteFilterOption('Products', $productName);
+ $this->formElement->selectAutocompleteActionFilterOptions([$productName], $channel->getCode(), 'products');
}
/**
@@ -686,7 +728,7 @@ final class ManagingPromotionsContext implements Context
{
$this->iWantToModifyAPromotion($promotion);
- Assert::same($this->updatePage->getPriority(), $priority);
+ Assert::same($this->formElement->getPriority(), $priority);
}
/**
@@ -757,17 +799,17 @@ final class ManagingPromotionsContext implements Context
/**
* @When I add a new rule
*/
- public function iAddANewRule()
+ public function iAddANewRule(): void
{
- $this->createPage->addRule(null);
+ $this->formElement->addRule(CartQuantityRuleChecker::TYPE);
}
/**
* @When I add a new action
*/
- public function iAddANewAction()
+ public function iAddANewAction(): void
{
- $this->createPage->addAction(null);
+ $this->formElement->addAction(FixedDiscountPromotionActionCommand::TYPE);
}
/**
@@ -789,9 +831,17 @@ final class ManagingPromotionsContext implements Context
/**
* @Then I should see the rule configuration form
*/
- public function iShouldSeeTheRuleConfigurationForm()
+ public function iShouldSeeTheRuleConfigurationForm(): void
{
- Assert::true($this->createPage->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.');
+ Assert::true($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.');
+ }
+
+ /**
+ * @Then I should not see the rule configuration form
+ */
+ public function iShouldNotSeeTheRuleConfigurationForm(): void
+ {
+ Assert::false($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is visible.');
}
/**
@@ -813,9 +863,17 @@ final class ManagingPromotionsContext implements Context
/**
* @Then I should see the action configuration form
*/
- public function iShouldSeeTheActionConfigurationForm()
+ public function iShouldSeeTheActionConfigurationForm(): void
{
- Assert::true($this->createPage->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.');
+ Assert::true($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.');
+ }
+
+ /**
+ * @Then I should not see the action configuration form
+ */
+ public function iShouldNotSeeTheActionConfigurationForm(): void
+ {
+ Assert::false($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is visible.');
}
/**
@@ -850,11 +908,8 @@ final class ManagingPromotionsContext implements Context
*/
public function iShouldBeNotifiedThatPromotionLabelIsTooLong(string $localeCode): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
Assert::same(
- $currentPage->getValidationMessageForTranslation('label', $localeCode),
+ $this->formElement->getValidationMessageForTranslation('label', $localeCode),
'This value is too long. It should have 255 characters or less.',
);
}
@@ -883,12 +938,17 @@ final class ManagingPromotionsContext implements Context
Assert::false($this->indexPage->isArchivalFilterEnabled());
}
+ /**
+ * @Then the :promotion promotion should be successfully created
+ */
+ public function thePromotionShouldBeSuccessfullyCreated(PromotionInterface $promotion): void
+ {
+ $this->updatePage->verify(['id' => $promotion->getId()]);
+ }
+
private function assertFieldValidationMessage(string $element, string $expectedMessage)
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
+ Assert::same($this->formElement->getValidationMessage($element), $expectedMessage);
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php
index f25dd303a4..6839c1cf72 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php
@@ -194,7 +194,7 @@ class ManagingShippingCategoriesContext implements Context
*/
public function iShouldNotBeAbleToEditItsCode(): void
{
- Assert::true($this->updatePage->isCodeDisabled());
+ Assert::true($this->updatePage->isCodeDisabled(), 'Shipping category code should be disabled');
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php
index 6efea9bb28..cdc39dc49d 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php
@@ -14,34 +14,36 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
-use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
-use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
+use Sylius\Behat\Element\Admin\ShippingMethod\FormElementInterface;
use Sylius\Behat\Page\Admin\ShippingMethod\CreatePageInterface;
use Sylius\Behat\Page\Admin\ShippingMethod\IndexPageInterface;
use Sylius\Behat\Page\Admin\ShippingMethod\UpdatePageInterface;
-use Sylius\Behat\Service\NotificationCheckerInterface;
-use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
+use Sylius\Behat\Service\SharedStorageInterface;
+use Sylius\Component\Addressing\Model\ZoneInterface;
use Sylius\Component\Channel\Model\ChannelInterface;
+use Sylius\Component\Core\Formatter\StringInflector;
use Sylius\Component\Core\Model\ShippingMethodInterface;
+use Sylius\Component\Core\Shipping\Checker\Rule\OrderTotalGreaterThanOrEqualRuleChecker;
+use Sylius\Component\Core\Shipping\Checker\Rule\OrderTotalLessThanOrEqualRuleChecker;
+use Sylius\Component\Shipping\Checker\Rule\TotalWeightGreaterThanOrEqualRuleChecker;
+use Sylius\Component\Shipping\Checker\Rule\TotalWeightLessThanOrEqualRuleChecker;
use Webmozart\Assert\Assert;
-final class ManagingShippingMethodsContext implements Context
+final readonly class ManagingShippingMethodsContext implements Context
{
- use ValidationTrait;
-
public function __construct(
private IndexPageInterface $indexPage,
private CreatePageInterface $createPage,
private UpdatePageInterface $updatePage,
- private CurrentPageResolverInterface $currentPageResolver,
- private NotificationCheckerInterface $notificationChecker,
+ private FormElementInterface $shippingMethodFormElement,
+ private SharedStorageInterface $sharedStorage,
) {
}
/**
* @When I want to create a new shipping method
*/
- public function iWantToCreateANewShippingMethod()
+ public function iWantToCreateANewShippingMethod(): void
{
$this->createPage->open();
}
@@ -52,56 +54,56 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iSpecifyItsCodeAs(?string $code = null): void
{
- $this->createPage->specifyCode($code ?? '');
+ $this->shippingMethodFormElement->setCode($code ?? '');
}
/**
* @When I specify its position as :position
*/
- public function iSpecifyItsPositionAs(?int $position = null)
+ public function iSpecifyItsPositionAs(int $position): void
{
- $this->createPage->specifyPosition($position);
+ $this->shippingMethodFormElement->setPosition($position);
}
/**
* @When I name it :name in :language
* @When I rename it to :name in :language
*/
- public function iNameItIn($name, $language)
+ public function iNameItIn(string $name, string $language): void
{
- $this->createPage->nameIt($name, $language);
+ $this->shippingMethodFormElement->setName($name, $language);
}
/**
* @When I describe it as :description in :language
*/
- public function iDescribeItAsIn($description, $language)
+ public function iDescribeItAsIn(string $description, string $language): void
{
- $this->createPage->describeIt($description, $language);
+ $this->shippingMethodFormElement->setDescription($description, $language);
}
/**
- * @When I define it for the zone named :zoneName
+ * @When I define it for the zone named :zone
*/
- public function iDefineItForTheZone(string $zoneName): void
+ public function iDefineItForTheZone(ZoneInterface $zone): void
{
- $this->createPage->chooseZone($zoneName);
+ $this->shippingMethodFormElement->setZoneCode($zone->getCode());
+ }
+
+ /**
+ * @When I make it available in channel :channel
+ */
+ public function iMakeItAvailableInChannel(ChannelInterface $channel): void
+ {
+ $this->shippingMethodFormElement->checkChannel($channel->getCode());
}
/**
* @When I specify its amount as :amount for :channel channel
*/
- public function iSpecifyItsAmountForChannel($amount, ChannelInterface $channel)
+ public function iSpecifyItsAmountForChannel(int $amount, ChannelInterface $channel): void
{
- $this->createPage->specifyAmountForChannel($channel->getCode(), $amount);
- }
-
- /**
- * @When I make it available in channel :channelName
- */
- public function iMakeItAvailableInChannel($channelName)
- {
- $this->createPage->checkChannel($channelName);
+ $this->shippingMethodFormElement->setCalculatorConfigurationAmountForChannel($channel->getCode(), $amount);
}
/**
@@ -117,9 +119,9 @@ final class ManagingShippingMethodsContext implements Context
* @When I choose :calculatorName calculator
* @When I do not specify amount for :calculatorName calculator
*/
- public function iChooseCalculator($calculatorName)
+ public function iChooseCalculator(string $calculatorName): void
{
- $this->createPage->chooseCalculator($calculatorName);
+ $this->shippingMethodFormElement->chooseCalculator($calculatorName);
}
/**
@@ -169,15 +171,22 @@ final class ManagingShippingMethodsContext implements Context
}
/**
- * @Then the shipping method :shippingMethod should be available in channel :channelName
+ * @Then the shipping method :shippingMethod should be available in channel :channel
*/
public function theShippingMethodShouldBeAvailableInChannel(
ShippingMethodInterface $shippingMethod,
- $channelName,
- ) {
+ ChannelInterface $channel,
+ ): void {
$this->iWantToModifyAShippingMethod($shippingMethod);
- Assert::true($this->updatePage->isAvailableInChannel($channelName));
+ Assert::true(
+ $this->shippingMethodFormElement->hasCheckedChannel($channel->getCode()),
+ sprintf(
+ 'Shipping method %s should be available in channel %s, but it is not.',
+ $shippingMethod->getName(),
+ $channel->getCode(),
+ ),
+ );
}
/**
@@ -185,7 +194,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iShouldBeNotifiedThatShippingMethodWithThisCodeAlreadyExists()
{
- Assert::same($this->createPage->getValidationMessage('code'), 'The shipping method with given code already exists.');
+ Assert::same($this->shippingMethodFormElement->getValidationMessage('code'), 'The shipping method with given code already exists.');
}
/**
@@ -212,7 +221,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function theCodeFieldShouldBeDisabled()
{
- Assert::true($this->updatePage->isCodeDisabled());
+ Assert::true($this->shippingMethodFormElement->isCodeDisabled());
}
/**
@@ -239,11 +248,25 @@ final class ManagingShippingMethodsContext implements Context
}
/**
- * @Then I should be notified that :element is required
+ * @Then /^I should be notified that (code) is required$/
*/
- public function iShouldBeNotifiedThatIsRequired($element)
+ public function iShouldBeNotifiedThatCodeIsRequired(string $field): void
{
- $this->assertFieldValidationMessage($element, sprintf('Please enter shipping method %s.', $element));
+ Assert::same(
+ $this->shippingMethodFormElement->getValidationMessage($field),
+ sprintf('Please enter shipping method %s.', $field),
+ );
+ }
+
+ /**
+ * @Then I should be notified that name is required
+ */
+ public function iShouldBeNotifiedThatNameIsRequired($localeCode = 'en_US'): void
+ {
+ Assert::same(
+ $this->shippingMethodFormElement->getValidationMessage('name', ['%localeCode%' => $localeCode]),
+ 'Please enter shipping method name.',
+ );
}
/**
@@ -260,19 +283,17 @@ final class ManagingShippingMethodsContext implements Context
/**
* @When I archive the :name shipping method
*/
- public function iArchiveTheShippingMethod($name)
+ public function iArchiveTheShippingMethod(string $name): void
{
- $actions = $this->indexPage->getActionsForResource(['name' => $name]);
- $actions->pressButton('Archive');
+ $this->indexPage->archiveShippingMethod($name);
}
/**
* @When I restore the :name shipping method
*/
- public function iRestoreTheShippingMethod($name)
+ public function iRestoreTheShippingMethod(string $name): void
{
- $actions = $this->indexPage->getActionsForResource(['name' => $name]);
- $actions->pressButton('Restore');
+ $this->indexPage->restoreShippingMethod($name);
}
/**
@@ -331,9 +352,9 @@ final class ManagingShippingMethodsContext implements Context
/**
* @When I remove its zone
*/
- public function iRemoveItsZone()
+ public function iRemoveItsZone(): void
{
- $this->updatePage->removeZone();
+ $this->shippingMethodFormElement->setZoneCode('');
}
/**
@@ -348,9 +369,9 @@ final class ManagingShippingMethodsContext implements Context
/**
* @When I remove its name from :language translation
*/
- public function iRemoveItsNameFromTranslation($language)
+ public function iRemoveItsNameFromTranslation(string $language): void
{
- $this->createPage->nameIt('', $language);
+ $this->shippingMethodFormElement->setName('', $language);
}
/**
@@ -417,7 +438,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iEnableIt()
{
- $this->updatePage->enable();
+ $this->shippingMethodFormElement->enable();
}
/**
@@ -425,7 +446,15 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iDisableIt()
{
- $this->updatePage->disable();
+ $this->shippingMethodFormElement->disable();
+ }
+
+ /**
+ * @When I specify a too long :field
+ */
+ public function iSpecifyATooLong(string $field): void
+ {
+ $this->shippingMethodFormElement->setField(ucwords($field), str_repeat('a', 256));
}
/**
@@ -433,7 +462,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function thisShippingMethodShouldBeDisabled(ShippingMethodInterface $shippingMethod)
{
- $this->assertShippingMethodState($shippingMethod, false);
+ Assert::true($this->indexPage->isShippingMethodDisabled($shippingMethod));
}
/**
@@ -441,7 +470,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function thisShippingMethodShouldBeEnabled(ShippingMethodInterface $shippingMethod)
{
- $this->assertShippingMethodState($shippingMethod, true);
+ Assert::true($this->indexPage->isShippingMethodEnabled($shippingMethod));
}
/**
@@ -450,8 +479,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iDeleteShippingMethod(ShippingMethodInterface $shippingMethod)
{
- $this->indexPage->open();
- $this->indexPage->deleteResourceOnPage(['name' => $shippingMethod->getName()]);
+ $this->indexPage->deleteShippingMethod($shippingMethod->getName());
}
/**
@@ -467,11 +495,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iShouldBeNotifiedThatAmountForChannelShouldNotBeBlank(ChannelInterface $channel)
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
Assert::same(
- $currentPage->getValidationMessageForAmount($channel->getCode()),
+ $this->shippingMethodFormElement->getValidationMessage('calculator_configuration_amount', ['%channelCode%' => $channel->getCode()]),
'This value should not be blank.',
);
}
@@ -481,11 +506,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iShouldBeNotifiedThatShippingChargeForChannelCannotBeLowerThan0(ChannelInterface $channel): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
Assert::same(
- $currentPage->getValidationMessageForAmount($channel->getCode()),
+ $this->shippingMethodFormElement->getValidationMessage('calculator_configuration_amount', ['%channelCode%' => $channel->getCode()]),
'Shipping charge cannot be lower than 0.',
);
}
@@ -495,8 +517,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iAddTheTotalWeightGreaterThanOrEqualRuleConfiguredWith(int $weight): void
{
- $this->createPage->addRule('Total weight greater than or equal');
- $this->createPage->fillRuleOption('Weight', (string) $weight);
+ $this->shippingMethodFormElement->addRule(TotalWeightGreaterThanOrEqualRuleChecker::TYPE);
+ $this->shippingMethodFormElement->fillLastRuleOption('Weight', (string) $weight);
}
/**
@@ -504,8 +526,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iAddTheTotalWeightGreaterThanOrEqualRuleConfiguredWithInvalidData(): void
{
- $this->createPage->addRule('Total weight greater than or equal');
- $this->createPage->fillRuleOption('Weight', 'invalid data');
+ $this->shippingMethodFormElement->addRule(TotalWeightGreaterThanOrEqualRuleChecker::TYPE);
+ $this->shippingMethodFormElement->fillLastRuleOption('Weight', 'invalid data');
}
/**
@@ -513,8 +535,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iAddTheTotalWeightLessThanOrEqualRuleConfiguredWith(int $weight): void
{
- $this->createPage->addRule('Total weight less than or equal');
- $this->createPage->fillRuleOption('Weight', (string) $weight);
+ $this->shippingMethodFormElement->addRule(TotalWeightLessThanOrEqualRuleChecker::TYPE);
+ $this->shippingMethodFormElement->fillLastRuleOption('Weight', (string) $weight);
}
/**
@@ -522,8 +544,13 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iAddTheItemsTotalLessThanOrEqualRuleConfiguredWith(string $rule, mixed $value, ChannelInterface $channel): void
{
- $this->createPage->addRule($rule);
- $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', (string) $value);
+ $ruleTypes = [
+ 'Items total less than or equal' => OrderTotalLessThanOrEqualRuleChecker::TYPE,
+ 'Items total greater than or equal' => OrderTotalGreaterThanOrEqualRuleChecker::TYPE,
+ ];
+
+ $this->shippingMethodFormElement->addRule($ruleTypes[$rule]);
+ $this->shippingMethodFormElement->fillLastRuleOptionForChannel($channel->getCode(), 'Amount', (string) $value);
}
/**
@@ -531,8 +558,8 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iAddTheItemsTotalLessThanOrEqualRuleConfiguredWithInvalidData(ChannelInterface $channel): void
{
- $this->createPage->addRule('Items total less than or equal');
- $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', 'Invalid data');
+ $this->shippingMethodFormElement->addRule(OrderTotalLessThanOrEqualRuleChecker::TYPE);
+ $this->shippingMethodFormElement->fillLastRuleOptionForChannel($channel->getCode(), 'Amount', 'Invalid data');
}
/**
@@ -540,7 +567,7 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iRemoveTheShippingChargesOfChannel(ChannelInterface $channel): void
{
- $this->updatePage->removeShippingChargesAmount($channel->getCode());
+ $this->shippingMethodFormElement->setCalculatorConfigurationAmountForChannel($channel->getCode(), null);
}
/**
@@ -551,7 +578,7 @@ final class ManagingShippingMethodsContext implements Context
int $count,
): void {
Assert::same(
- $this->updatePage->getShippingChargesValidationErrorsCount($channel->getCode()),
+ $this->shippingMethodFormElement->getShippingChargesValidationErrorsCount($channel->getCode()),
$count,
);
}
@@ -561,7 +588,11 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iShouldBeNotifiedThatTheWeightRuleHasAnInvalidConfiguration(): void
{
- $this->assertFieldValidationMessage('weight', 'Please enter a number.');
+ $channel = $this->sharedStorage->get('channel');
+ Assert::same(
+ $this->shippingMethodFormElement->getValidationMessage('last_rule_weight'),
+ 'Please enter a number.',
+ );
}
/**
@@ -569,42 +600,37 @@ final class ManagingShippingMethodsContext implements Context
*/
public function iShouldBeNotifiedThatTheAmountRuleHasAnInvalidConfigurationInChannel(ChannelInterface $channel): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
Assert::same(
- $currentPage->getValidationMessageForRuleAmount($channel->getCode()),
+ $this->shippingMethodFormElement->getValidationMessage('last_rule_amount', ['%channelCode%' => $channel->getCode()]),
'Please enter a valid money amount.',
);
}
/**
- * @param string $element
- * @param string $expectedMessage
+ * @Then I should be notified that :field is too long
+ * @Then I should be notified that :field should be no longer than :maxLength characters
*/
- private function assertFieldValidationMessage($element, $expectedMessage)
+ public function iShouldBeNotifiedThatFieldValueIsTooLong(string $field, int $maxLength = 255): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
+ $validationMessage = $this->shippingMethodFormElement->getValidationMessage(StringInflector::nameToLowercaseCode($field));
- Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
+ Assert::contains(
+ $validationMessage,
+ sprintf('must not be longer than %d characters.', $maxLength),
+ );
}
/**
- * @param bool $state
+ * @Then the :shippingMethod shipping method should be successfully created
*/
- private function assertShippingMethodState(ShippingMethodInterface $shippingMethod, $state)
+ public function theShippingMethodShouldBeSuccessfullyCreated(ShippingMethodInterface $shippingMethod): void
{
- $this->iWantToBrowseShippingMethods();
-
- Assert::true($this->indexPage->isSingleResourceOnPage([
- 'name' => $shippingMethod->getName(),
- 'enabled' => $state ? 'Enabled' : 'Disabled',
- ]));
+ $this->updatePage->verify(['id' => $shippingMethod->getId()]);
+ $this->theShipmentMethodShouldAppearInTheRegistry($shippingMethod->getName());
}
- protected function resolveCurrentPage(): SymfonyPageInterface
+ private function assertFieldValidationMessage(string $element, string $expectedMessage): void
{
- return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
+ Assert::same($this->shippingMethodFormElement->getValidationMessage($element), $expectedMessage);
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php
index 6e2bf03913..c181989bda 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php
@@ -237,7 +237,7 @@ final class ManagingTaxRateContext implements Context
*/
public function iShouldBeNotifiedThatTaxRateWithThisCodeAlreadyExists()
{
- Assert::same($this->createPage->getValidationMessage('code'), 'The tax rate with given code already exists.');
+ $this->assertFieldValidationMessage('code', 'The tax rate with given code already exists.');
}
/**
@@ -356,35 +356,6 @@ final class ManagingTaxRateContext implements Context
Assert::same($this->indexPage->countItems(), 1);
}
- /**
- * @param string $element
- * @param string $taxRateElement
- */
- private function assertFieldValue(TaxRateInterface $taxRate, $element, $taxRateElement)
- {
- $this->indexPage->open();
-
- Assert::true(
- $this->indexPage->isSingleResourceOnPage([
- 'code' => $taxRate->getCode(),
- $element => $taxRateElement,
- ]),
- sprintf('Tax rate %s %s has not been assigned properly.', $element, $taxRateElement),
- );
- }
-
- /**
- * @param string $element
- * @param string $expectedMessage
- */
- private function assertFieldValidationMessage($element, $expectedMessage)
- {
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
- }
-
/**
* @Given I choose "Included in price" option
*/
@@ -429,8 +400,29 @@ final class ManagingTaxRateContext implements Context
$this->filterElement->filter();
}
+ private function assertFieldValue(TaxRateInterface $taxRate, string $element, string $taxRateElement): void
+ {
+ $this->indexPage->open();
+
+ Assert::true(
+ $this->indexPage->isSingleResourceOnPage([
+ 'code' => $taxRate->getCode(),
+ $element => $taxRateElement,
+ ]),
+ sprintf('Tax rate %s %s has not been assigned properly.', $element, $taxRateElement),
+ );
+ }
+
protected function resolveCurrentPage(): SymfonyPageInterface
{
return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
}
+
+ private function assertFieldValidationMessage(string $element, string $expectedMessage): void
+ {
+ /** @var CreatePageInterface|UpdatePageInterface $currentPage */
+ $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
+
+ Assert::same($currentPage->getValidationMessage('field_' . $element), $expectedMessage);
+ }
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php
index b5f53a2fa8..54a4ffea7c 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php
@@ -16,6 +16,8 @@ namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
+use Sylius\Behat\Element\Admin\Taxon\FormElementInterface;
+use Sylius\Behat\Element\Admin\Taxon\ImageFormElementInterface;
use Sylius\Behat\NotificationType;
use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface;
use Sylius\Behat\Page\Admin\Taxon\CreateForParentPageInterface;
@@ -34,14 +36,16 @@ final class ManagingTaxonsContext implements Context
use ValidationTrait;
public function __construct(
- private SharedStorageInterface $sharedStorage,
- private CreatePageInterface $createPage,
- private CreateForParentPageInterface $createForParentPage,
- private UpdatePageInterface $updatePage,
- private CurrentPageResolverInterface $currentPageResolver,
- private NotificationCheckerInterface $notificationChecker,
- private JavaScriptTestHelper $testHelper,
- private UpdateSimpleProductPageInterface $updateSimpleProductPage,
+ private readonly SharedStorageInterface $sharedStorage,
+ private readonly CreatePageInterface $createPage,
+ private readonly CreateForParentPageInterface $createForParentPage,
+ private readonly UpdatePageInterface $updatePage,
+ private readonly FormElementInterface $formElement,
+ private readonly ImageFormElementInterface $imageFormElement,
+ private readonly CurrentPageResolverInterface $currentPageResolver,
+ private readonly NotificationCheckerInterface $notificationChecker,
+ private readonly JavaScriptTestHelper $testHelper,
+ private readonly UpdateSimpleProductPageInterface $updateSimpleProductPage,
) {
}
@@ -86,11 +90,9 @@ final class ManagingTaxonsContext implements Context
* @When I rename it to :name in :language
* @When I do not specify its name
*/
- public function iNameItIn(?string $name = null, $language = 'en_US')
+ public function iNameItIn(?string $name = null, $language = 'en_US'): void
{
- $currentPage = $this->resolveCurrentPage();
-
- $currentPage->nameIt($name ?? '', $language);
+ $this->formElement->nameIt($name ?? '', $language);
}
/**
@@ -98,11 +100,9 @@ final class ManagingTaxonsContext implements Context
* @When I do not specify its slug
* @When I set its slug to :slug in :language
*/
- public function iSetItsSlugToIn(?string $slug = null, $language = 'en_US')
+ public function iSetItsSlugToIn(?string $slug = null, $language = 'en_US'): void
{
- $currentPage = $this->resolveCurrentPage();
-
- $currentPage->specifySlug($slug ?? '', $language);
+ $this->formElement->slugIt($slug ?? '', $language);
}
/**
@@ -172,10 +172,10 @@ final class ManagingTaxonsContext implements Context
/**
* @Then /^the ("[^"]+" taxon) should appear in the registry$/
*/
- public function theTaxonShouldAppearInTheRegistry(TaxonInterface $taxon)
+ public function theTaxonShouldAppearInTheRegistry(TaxonInterface $taxon): void
{
$this->updatePage->open(['id' => $taxon->getId()]);
- Assert::true($this->updatePage->hasResourceValues(['code' => $taxon->getCode()]));
+ Assert::same($this->formElement->getCode(), $taxon->getCode());
}
/**
@@ -309,9 +309,7 @@ final class ManagingTaxonsContext implements Context
*/
public function iAttachImageWithType(string $path, ?string $type = null): void
{
- $currentPage = $this->resolveCurrentPage();
-
- $currentPage->attachImage($path, $type);
+ $this->imageFormElement->attachImage($path, $type);
}
/**
@@ -327,7 +325,7 @@ final class ManagingTaxonsContext implements Context
*/
public function thisTaxonShouldHaveAnImageWithType(string $type): void
{
- Assert::true($this->updatePage->isImageWithTypeDisplayed($type));
+ Assert::true($this->imageFormElement->isImageWithTypeDisplayed($type));
}
/**
@@ -335,7 +333,7 @@ final class ManagingTaxonsContext implements Context
*/
public function thisTaxonShouldNotHaveAnImageWithType($code)
{
- Assert::false($this->updatePage->isImageWithTypeDisplayed($code));
+ Assert::false($this->imageFormElement->isImageWithTypeDisplayed($code));
}
/**
@@ -343,52 +341,52 @@ final class ManagingTaxonsContext implements Context
*/
public function iRemoveAnImageWithType(string $type): void
{
- $this->updatePage->removeImageWithType($type);
+ $this->imageFormElement->removeImageWithType($type);
}
/**
* @When I remove the first image
*/
- public function iRemoveTheFirstImage()
+ public function iRemoveTheFirstImage(): void
{
- $this->updatePage->removeFirstImage();
+ $this->imageFormElement->removeFirstImage();
}
/**
* @Then /^(this taxon) should not have any images$/
*/
- public function thisTaxonShouldNotHaveAnyImages(TaxonInterface $taxon)
+ public function thisTaxonShouldNotHaveAnyImages(TaxonInterface $taxon): void
{
$this->iWantToModifyATaxon($taxon);
- Assert::same($this->updatePage->countImages(), 0);
+ Assert::same($this->imageFormElement->countImages(), 0);
}
/**
* @When I change the image with the :type type to :path
*/
- public function iChangeItsImageToPathForTheType($path, $type)
+ public function iChangeItsImageToPathForTheType($path, $type): void
{
- $this->updatePage->changeImageWithType($type, $path);
+ $this->imageFormElement->changeImageWithType($type, $path);
}
/**
* @When I change the first image type to :type
*/
- public function iChangeTheFirstImageTypeTo($type)
+ public function iChangeTheFirstImageTypeTo($type): void
{
- $this->updatePage->modifyFirstImageType($type);
+ $this->imageFormElement->modifyFirstImageType($type);
}
/**
* @Then /^(this taxon) should have only one image$/
* @Then /^(this taxon) should(?:| still) have (\d+) images?$/
*/
- public function thereShouldStillBeOnlyOneImageInThisTaxon(TaxonInterface $taxon, $count = 1)
+ public function thereShouldStillBeOnlyOneImageInThisTaxon(TaxonInterface $taxon, $count = 1): void
{
$this->iWantToModifyATaxon($taxon);
- Assert::same($this->updatePage->countImages(), (int) $count);
+ Assert::same($this->imageFormElement->countImages(), (int) $count);
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php
index 5bf6354c3a..b28b46fbd0 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php
@@ -15,27 +15,22 @@ namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
use Behat\Mink\Exception\ElementNotFoundException;
-use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
-use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
+use Sylius\Behat\Element\Admin\Zone\FormElementInterface;
use Sylius\Behat\NotificationType;
+use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
-use Sylius\Behat\Page\Admin\Zone\CreatePageInterface;
-use Sylius\Behat\Page\Admin\Zone\UpdatePageInterface;
+use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
use Sylius\Behat\Service\NotificationCheckerInterface;
-use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
use Sylius\Component\Addressing\Model\ZoneInterface;
-use Sylius\Component\Addressing\Model\ZoneMemberInterface;
use Webmozart\Assert\Assert;
final class ManagingZonesContext implements Context
{
- use ValidationTrait;
-
public function __construct(
- private CreatePageInterface $createPage,
private IndexPageInterface $indexPage,
+ private CreatePageInterface $createPage,
private UpdatePageInterface $updatePage,
- private CurrentPageResolverInterface $currentPageResolver,
+ private FormElementInterface $formElement,
private NotificationCheckerInterface $notificationChecker,
) {
}
@@ -43,7 +38,7 @@ final class ManagingZonesContext implements Context
/**
* @When I want to create a new zone consisting of :memberType
*/
- public function iWantToCreateANewZoneWithMembers($memberType)
+ public function iWantToCreateANewZoneWithMembers(string $memberType): void
{
$this->createPage->open(['type' => $memberType]);
}
@@ -52,7 +47,7 @@ final class ManagingZonesContext implements Context
* @When I browse zones
* @When I want to see all zones in store
*/
- public function iWantToSeeAllZonesInStore()
+ public function iWantToSeeAllZonesInStore(): void
{
$this->indexPage->open();
}
@@ -60,108 +55,88 @@ final class ManagingZonesContext implements Context
/**
* @When /^I want to modify the (zone named "[^"]+")$/
*/
- public function iWantToModifyAZoneNamed(ZoneInterface $zone)
+ public function iWantToModifyAZoneNamed(ZoneInterface $zone): void
{
$this->updatePage->open(['id' => $zone->getId()]);
}
/**
- * @When /^I(?:| try to) delete the (zone named "([^"]*)")$/
+ * @When /^I(?:| try to) delete the (zone named "([^"]+)")$/
*/
- public function iDeleteZoneNamed(ZoneInterface $zone)
+ public function iDeleteZoneNamed(ZoneInterface $zone): void
{
$this->indexPage->open();
$this->indexPage->deleteResourceOnPage(['name' => $zone->getName(), 'code' => $zone->getCode()]);
}
/**
- * @When /^I(?:| also) remove (the "([^"]*)" (?:country|province|zone) member)$/
+ * @When /^I(?:| also) remove the "([^"]+)" (?:country|province|zone) member$/
+ * @When /^I(?:| also) remove the "([^"]+)", "([^"]+)" and "([^"]+)" (?:country|province|zone) members$/
*/
- public function iRemoveTheMember(ZoneMemberInterface $zoneMember)
+ public function iRemoveMembers(string ...$members): void
{
- $this->updatePage->removeMember($zoneMember);
- }
-
- /**
- * @When /^I(?:| also) remove the ("([^"]+)", "([^"]+)" and "([^"]+)" (?:country|province|zone) members)$/
- */
- public function iRemoveMembers(array $countries): void
- {
- foreach ($countries as $country) {
- $this->updatePage->removeMember($country);
+ foreach ($members as $member) {
+ $this->formElement->removeMember($member);
}
}
- /**
- * @When I rename it to :name
- */
- public function iRenameItTo($name)
- {
- $this->updatePage->nameIt($name ?? '');
- }
-
/**
* @When I name it :name
+ * @When I rename it to :name
+ * @When I do not specify its name
*/
- public function iNameIt($name)
+ public function iNameIt(string $name = ''): void
{
- $this->createPage->nameIt($name ?? '');
+ $this->formElement->nameIt($name);
}
/**
* @When I specify its code as :code
- */
- public function iSpecifyItsCodeAs(?string $code = null): void
- {
- $this->createPage->specifyCode($code ?? '');
- }
-
- /**
* @When I do not specify its code
*/
- public function iDoNotSpecifyItsCode()
+ public function iSpecifyItsCodeAs(string $code = ''): void
{
- // Intentionally left blank to fulfill context expectation
+ $this->formElement->specifyCode($code);
}
/**
- * @When I do not specify its name
+ * @When I specify a too long code
*/
- public function iDoNotSpecifyItsName()
+ public function iSpecifyATooLong(): void
{
- // Intentionally left blank to fulfill context expectation
+ $this->formElement->specifyCode(str_repeat('a', 256));
}
/**
* @When I do not add a country member
*/
- public function iDoNotAddACountryMember()
+ public function iDoNotAddACountryMember(): void
{
// Intentionally left blank to fulfill context expectation
}
/**
- * @When /^I add a(?: country| province| zone) "([^"]+)"$/
+ * @When /^I add a (?:country|province|zone) "([^"]+)"$/
*/
- public function iAddAZoneMember($name)
+ public function iAddAZoneMember(string $name): void
{
- $this->createPage->addMember();
- $this->createPage->chooseMember($name);
+ $this->formElement->addMember();
+ $this->formElement->chooseMember($name);
}
/**
* @When I select its scope as :scope
*/
- public function iSelectItsScopeAs($scope)
+ public function iSelectItsScopeAs($scope): void
{
- $this->createPage->selectScope($scope);
+ $this->formElement->selectScope($scope);
}
/**
* @When I add it
* @When I try to add it
*/
- public function iAddIt()
+ public function iAddIt(): void
{
$this->createPage->create();
}
@@ -169,7 +144,7 @@ final class ManagingZonesContext implements Context
/**
* @When I save my changes
*/
- public function iSaveMyChanges()
+ public function iSaveMyChanges(): void
{
$this->updatePage->saveChanges();
}
@@ -191,37 +166,53 @@ final class ManagingZonesContext implements Context
}
/**
- * @Then /^the (zone named "[^"]+") with (the "[^"]+" (?:country|province|zone) member) should appear in the registry$/
+ * @Then /^the (zone named "[^"]+") with the "([^"]+)" (?:country|province|zone) member should appear in the registry$/
*/
- public function theZoneWithTheCountryShouldAppearInTheRegistry(ZoneInterface $zone, ZoneMemberInterface $zoneMember)
- {
- $this->assertZoneAndItsMember($zone, $zoneMember);
+ public function theZoneWithTheCountryShouldAppearInTheRegistry(
+ ZoneInterface $zone,
+ string $member,
+ ): void {
+ $this->updatePage->open(['id' => $zone->getId()]);
+
+ Assert::same($this->formElement->getName(), $zone->getName());
+ Assert::true(
+ $this->formElement->hasMember($member),
+ sprintf('Zone %s has no member %s', $zone->getName(), $member),
+ );
}
/**
* @Given its scope should be :scope
*/
- public function itsScopeShouldBe($scope)
+ public function itsScopeShouldBe(string $scope): void
{
- Assert::same($this->updatePage->getScope(), $scope);
+ Assert::same($this->formElement->getScope(), $scope);
}
/**
- * @Then /^(this zone) should have only (the "([^"]*)" (?:country|province|zone) member)$/
+ * @Then /^(this zone) should have only the "([^"]*)" (?:country|province|zone) member$/
*/
- public function thisZoneShouldHaveOnlyTheProvinceMember(ZoneInterface $zone, ZoneMemberInterface $zoneMember)
- {
- $this->assertZoneAndItsMember($zone, $zoneMember);
+ public function thisZoneShouldHaveOnlyTheMember(
+ ZoneInterface $zone,
+ string $member,
+ ): void {
+ $this->updatePage->open(['id' => $zone->getId()]);
- Assert::same($this->updatePage->countMembers(), 1);
+ Assert::same($this->formElement->countMembers(), 1);
+ Assert::true(
+ $this->formElement->hasMember($member),
+ sprintf('Zone %s has no member %s', $zone->getName(), $member),
+ );
}
/**
* @Then /^(this zone) name should be "([^"]*)"/
*/
- public function thisZoneNameShouldBe(ZoneInterface $zone, $name)
+ public function thisZoneNameShouldBe(ZoneInterface $zone, string $name): void
{
- Assert::true($this->updatePage->hasResourceValues(['code' => $zone->getCode(), 'name' => $name]));
+ $this->updatePage->open(['id' => $zone->getId()]);
+
+ Assert::same($this->formElement->getName(), $name);
}
/**
@@ -229,24 +220,21 @@ final class ManagingZonesContext implements Context
*/
public function iShouldNotBeAbleToEditItsCode(): void
{
- Assert::true($this->updatePage->isCodeDisabled());
+ Assert::true($this->formElement->isCodeDisabled());
}
/**
* @Then /^I should be notified that zone with this code already exists$/
*/
- public function iShouldBeNotifiedThatZoneWithThisCodeAlreadyExists()
+ public function iShouldBeNotifiedThatZoneWithThisCodeAlreadyExists(): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage('code'), 'Zone code must be unique.');
+ Assert::same($this->formElement->getValidationMessage('code'), 'Zone code must be unique.');
}
/**
* @Then /^there should still be only one zone with code "([^"]*)"$/
*/
- public function thereShouldStillBeOnlyOneZoneWithCode($code)
+ public function thereShouldStillBeOnlyOneZoneWithCode(string $code): void
{
$this->indexPage->open();
@@ -256,18 +244,15 @@ final class ManagingZonesContext implements Context
/**
* @Then I should be notified that :element is required
*/
- public function iShouldBeNotifiedThatIsRequired($element)
+ public function iShouldBeNotifiedThatIsRequired(string $element): void
{
- /** @var CreatePageInterface|UpdatePageInterface $currentPage */
- $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
-
- Assert::same($currentPage->getValidationMessage($element), sprintf('Please enter zone %s.', $element));
+ Assert::same($this->formElement->getValidationMessage($element), sprintf('Please enter zone %s.', $element));
}
/**
* @Then zone with :element :value should not be added
*/
- public function zoneWithNameShouldNotBeAdded($element, $value)
+ public function zoneWithNameShouldNotBeAdded(string $element, string $value): void
{
$this->indexPage->open();
@@ -277,9 +262,9 @@ final class ManagingZonesContext implements Context
/**
* @Then /^I should be notified that at least one zone member is required$/
*/
- public function iShouldBeNotifiedThatAtLeastOneZoneMemberIsRequired()
+ public function iShouldBeNotifiedThatAtLeastOneZoneMemberIsRequired(): void
{
- Assert::true($this->createPage->checkValidationMessageForMembers('Please add at least 1 zone member.'));
+ Assert::same($this->formElement->getFormValidationMessage(), 'Please add at least 1 zone member.');
}
/**
@@ -287,21 +272,24 @@ final class ManagingZonesContext implements Context
*/
public function iShouldNotBeAbleToEditItsType(): void
{
- Assert::true($this->createPage->isTypeFieldDisabled());
+ Assert::true($this->formElement->isTypeFieldDisabled());
}
/**
* @Then it should be of :type type
*/
- public function itShouldBeOfType($type)
+ public function itShouldBeOfType(string $type): void
{
- Assert::true($this->createPage->hasType($type));
+ Assert::same(
+ strtolower($this->formElement->getType()),
+ strtolower($type),
+ );
}
/**
* @Then the zone named :zoneName should no longer exist in the registry
*/
- public function thisZoneShouldNoLongerExistInTheRegistry($zoneName)
+ public function thisZoneShouldNoLongerExistInTheRegistry(string $zoneName): void
{
Assert::false($this->indexPage->isSingleResourceOnPage(['name' => $zoneName]));
}
@@ -318,13 +306,14 @@ final class ManagingZonesContext implements Context
/**
* @Then /^I should(?:| still) see the (zone named "([^"]+)") in the list$/
*/
- public function iShouldSeeTheZoneNamedInTheList(ZoneInterface $zone)
+ public function iShouldSeeTheZoneNamedInTheList(ZoneInterface $zone): void
{
Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $zone->getCode(), 'name' => $zone->getName()]));
}
/**
* @Then I should be notified that the zone is in use and cannot be deleted
+ * @Then I should be notified that this zone cannot be deleted
*/
public function iShouldBeNotifiedThatTheZoneIsInUseAndCannotBeDeleted(): void
{
@@ -332,45 +321,29 @@ final class ManagingZonesContext implements Context
}
/**
- * @Then I should be notified that this zone cannot be deleted
+ * @Then I should be notified that code is too long
*/
- public function iShouldBeNotifiedThatThisZoneCannotBeDeleted(): void
+ public function iShouldBeNotifiedThatCodeIsTooLong(): void
{
- $this->notificationChecker->checkNotification('Error Cannot delete, the zone is in use.', NotificationType::failure());
- }
-
- /**
- * @throws \InvalidArgumentException
- */
- private function assertZoneAndItsMember(ZoneInterface $zone, ZoneMemberInterface $zoneMember)
- {
- Assert::true(
- $this->updatePage->hasResourceValues([
- 'code' => $zone->getCode(),
- 'name' => $zone->getName(),
- ]),
- sprintf('Zone %s is not valid', $zone->getName()),
+ Assert::contains(
+ $this->formElement->getValidationMessage('code'),
+ 'must not be longer than 255 characters.',
);
-
- Assert::true($this->updatePage->hasMember($zoneMember));
}
/**
- * @Then /^I can not add a(?: country| province| zone) "([^"]+)"$/
+ * @Then /^I should not be able to add the "([^"]+)" (?:country|province|zone) as a member$/
*/
- public function iCanNotAddAZoneMember($name)
+ public function iShouldNotBeAbleToAddTheMember(string $name): void
{
- $member = null;
+ $this->formElement->addMember();
try {
- $member = $this->createPage->chooseMember($name);
+ $this->formElement->chooseMember($name);
} catch (ElementNotFoundException) {
+ return;
}
- Assert::isEmpty($member);
- }
- protected function resolveCurrentPage(): SymfonyPageInterface
- {
- return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
+ throw new \InvalidArgumentException(sprintf('Member "%s" should not be selectable.', $name));
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php b/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php
index 2ae6cc8be4..3c4f05cc58 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php
@@ -14,15 +14,14 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
+use Sylius\Behat\Element\Admin\NotificationsElementInterface;
use Sylius\Behat\NotificationType;
-use Sylius\Behat\Service\Helper\JavaScriptTestHelperInterface;
-use Sylius\Behat\Service\NotificationCheckerInterface;
+use Webmozart\Assert\Assert;
-final class NotificationContext implements Context
+final readonly class NotificationContext implements Context
{
public function __construct(
- private NotificationCheckerInterface $notificationChecker,
- private JavaScriptTestHelperInterface $testHelper,
+ private NotificationsElementInterface $notificationsElement,
) {
}
@@ -31,11 +30,7 @@ final class NotificationContext implements Context
*/
public function iShouldBeNotifiedItHasBeenSuccessfullyCreated(): void
{
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::success(),
- 'has been successfully created.',
- );
+ Assert::true($this->notificationsElement->hasNotification((string) NotificationType::success(), 'has been successfully created.'));
}
/**
@@ -45,11 +40,7 @@ final class NotificationContext implements Context
*/
public function iShouldBeNotifiedThatItHasBeenSuccessfullyEdited(): void
{
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::success(),
- 'has been successfully updated.',
- );
+ Assert::true($this->notificationsElement->hasNotification((string) NotificationType::success(), 'has been successfully updated.'));
}
/**
@@ -58,10 +49,11 @@ final class NotificationContext implements Context
*/
public function iShouldBeNotifiedThatItHasBeenSuccessfullyDeleted(string $hasHave): void
{
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::success(),
- sprintf('%s been successfully deleted.', $hasHave),
+ Assert::true(
+ $this->notificationsElement->hasNotification(
+ (string) NotificationType::success(),
+ sprintf('%s been successfully deleted.', $hasHave),
+ ),
);
}
@@ -70,10 +62,11 @@ final class NotificationContext implements Context
*/
public function iShouldBeNotifiedThatTheRemovalOperationHasStartedSuccessfully(): void
{
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::success(),
- 'has been requested. This process can take a while depending on the number of affected products.',
+ Assert::true(
+ $this->notificationsElement->hasNotification(
+ (string) NotificationType::success(),
+ 'has been requested. This process can take a while depending on the number of affected products.',
+ ),
);
}
@@ -82,10 +75,6 @@ final class NotificationContext implements Context
*/
public function iShouldBeNotifiedThatItIsInUse(): void
{
- $this->testHelper->waitUntilNotificationPopups(
- $this->notificationChecker,
- NotificationType::failure(),
- 'Cannot delete',
- );
+ Assert::true($this->notificationsElement->hasNotification((string) NotificationType::error(), 'Cannot delete'));
}
}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php b/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php
new file mode 100644
index 0000000000..70c924090f
--- /dev/null
+++ b/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php
@@ -0,0 +1,51 @@
+historyPage->open(['id' => $order->getId()]);
+ }
+
+ /**
+ * @Then there should be :count shipping address changes in the registry
+ */
+ public function thereShouldBeCountShippingAddressChangesInTheRegistry(int $count): void
+ {
+ Assert::same($this->historyPage->countShippingAddressChanges(), $count);
+ }
+
+ /**
+ * @Then there should be :count billing address changes in the registry
+ */
+ public function thereShouldBeCountBillingAddressChangesInTheRegistry(int $count): void
+ {
+ Assert::same($this->historyPage->countBillingAddressChanges(), $count);
+ }
+}
diff --git a/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php b/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php
index 88f68e2cca..ecdd5c1b3e 100644
--- a/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php
+++ b/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php
@@ -114,7 +114,7 @@ final class ProductShowPageContext implements Context
public function iAccessThePriceHistoryIndexPageOfSimpleProductForChannel(string $channelName): void
{
$pricingRow = $this->pricingElement->getSimpleProductPricingRowForChannel($channelName);
- $pricingRow->clickLink('Show');
+ $pricingRow->find('css', '[data-test-price-history]')->click();
}
/**
@@ -123,7 +123,7 @@ final class ProductShowPageContext implements Context
public function iAccessThePriceHistoryIndexPageOfVariantForChannel(string $variantName, string $channelName): void
{
$pricingRow = $this->pricingElement->getVariantPricingRowForChannel($variantName, $channelName);
- $pricingRow->clickLink('Show');
+ $pricingRow->find('css', '[data-test-price-history]')->click();
}
/**
diff --git a/src/Sylius/Behat/Context/Ui/CustomerContext.php b/src/Sylius/Behat/Context/Ui/CustomerContext.php
index 997214bfa9..c81a6c515d 100644
--- a/src/Sylius/Behat/Context/Ui/CustomerContext.php
+++ b/src/Sylius/Behat/Context/Ui/CustomerContext.php
@@ -54,6 +54,6 @@ final class CustomerContext implements Context
$this->customerShowPage->open(['id' => $deletedUser->getCustomer()->getId()]);
- Assert::false($this->customerShowPage->isRegistered());
+ Assert::false($this->customerShowPage->hasAccount());
}
}
diff --git a/src/Sylius/Behat/Context/Ui/ThemeContext.php b/src/Sylius/Behat/Context/Ui/ThemeContext.php
index bc3b95b2d4..8406ef3bcc 100644
--- a/src/Sylius/Behat/Context/Ui/ThemeContext.php
+++ b/src/Sylius/Behat/Context/Ui/ThemeContext.php
@@ -51,7 +51,7 @@ final class ThemeContext implements Context
public function iUnsetThemeOnChannel(ChannelInterface $channel)
{
$this->channelUpdatePage->open(['id' => $channel->getId()]);
- $this->channelUpdatePage->unsetTheme();
+ $this->channelUpdatePage->setTheme('');
$this->channelUpdatePage->saveChanges();
}
diff --git a/src/Sylius/Behat/Context/Ui/UserContext.php b/src/Sylius/Behat/Context/Ui/UserContext.php
index 53acd1af67..27c6d0fe5c 100644
--- a/src/Sylius/Behat/Context/Ui/UserContext.php
+++ b/src/Sylius/Behat/Context/Ui/UserContext.php
@@ -62,6 +62,6 @@ final class UserContext implements Context
$this->customerShowPage->open(['id' => $deletedUser->getCustomer()->getId()]);
- Assert::false($this->customerShowPage->isRegistered());
+ Assert::false($this->customerShowPage->hasAccount());
}
}
diff --git a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php
index 7bfeb5c9ad..2abc4ef87d 100644
--- a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php
+++ b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php
@@ -14,14 +14,21 @@ declare(strict_types=1);
namespace Sylius\Behat\Element\Admin\CatalogPromotion;
use Behat\Mink\Element\NodeElement;
-use Behat\Mink\Exception\ElementNotFoundException;
-use FriendsOfBehat\PageObjectExtension\Element\Element;
+use Behat\Mink\Session;
+use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Behat\Service\TabsHelper;
-use Sylius\Component\Core\Model\ChannelInterface;
-use Webmozart\Assert\Assert;
-final class FormElement extends Element implements FormElementInterface
+final class FormElement extends BaseFormElement implements FormElementInterface
{
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ private readonly AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters);
+ }
+
public function nameIt(string $name): void
{
$this->getElement('name')->setValue($name);
@@ -29,12 +36,12 @@ final class FormElement extends Element implements FormElementInterface
public function labelIt(string $label, string $localeCode): void
{
- $this->getElement('label', ['%localeCode%' => $localeCode])->setValue($label);
+ $this->getElement('label', ['%locale_code%' => $localeCode])->setValue($label);
}
public function describeIt(string $description, string $localeCode): void
{
- $this->getElement('description', ['%localeCode%' => $localeCode])->setValue($description);
+ $this->getElement('description', ['%locale_code%' => $localeCode])->setValue($description);
}
public function prioritizeIt(int $priority): void
@@ -49,7 +56,7 @@ final class FormElement extends Element implements FormElementInterface
public function checkChannel(string $channelName): void
{
- $this->getDocument()->checkField($channelName);
+ $this->getElement('channels')->checkField($channelName);
}
public function setExclusiveness(bool $isExclusive): void
@@ -59,190 +66,158 @@ final class FormElement extends Element implements FormElementInterface
public function uncheckChannel(string $channelName): void
{
- $this->getDocument()->uncheckField($channelName);
+ $this->getElement('channels')->uncheckField($channelName);
}
public function specifyStartDate(\DateTimeInterface $startDate): void
{
$timestamp = $startDate->getTimestamp();
- $this->getElement('start_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('start_date_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('start_date_time')->setValue(date('H:i', $timestamp));
}
public function specifyEndDate(\DateTimeInterface $endDate): void
{
$timestamp = $endDate->getTimestamp();
- $this->getElement('end_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('end_date_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('end_date_time')->setValue(date('H:i', $timestamp));
}
- public function addScope(): void
+ public function addScope(string $type): void
{
- $this->addCollectionElement('scopes', 'add_scope_button');
+ $this->getElement('add_scope_button', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
}
- public function addAction(): void
+ public function addAction(string $type): void
{
- $this->addCollectionElement('actions', 'add_action_button');
+ $this->getElement('add_action_button', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
}
- public function chooseScopeType(string $type): void
+ public function selectScopeOption(array $values): void
{
$lastScope = $this->getElement('last_scope');
+ foreach ($values as $value) {
+ $this->autocompleteHelper->selectByValue(
+ $this->getDriver(),
+ $lastScope->find('css', 'select')->getXpath(),
+ $value,
+ );
+ }
- $lastScope->selectFieldOption('Type', $type);
+ $this->waitForFormUpdate();
}
- public function chooseActionType(string $type): void
+ public function fillActionOption(string $option, string $value): void
{
$lastAction = $this->getElement('last_action');
- $lastAction->selectFieldOption('Type', $type);
+ $lastAction->fillField($option, $value);
}
- public function chooseLastScopeCodes(array $codes): void
- {
- $lastScope = $this->getElement('last_scope');
-
- $lastScope->find('css', 'input[type="hidden"]')->setValue(implode(',', $codes));
- }
-
- public function specifyLastActionDiscount(string $discount): void
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void
{
$lastAction = $this->getElement('last_action');
- $lastAction->find('css', 'input')->setValue($discount);
- }
+ TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
- public function specifyLastActionDiscountForChannel(string $discount, ChannelInterface $channel): void
- {
- $lastAction = $this->getElement('last_action');
-
- TabsHelper::switchTab($this->getSession(), $lastAction, $channel->getCode());
-
- $lastAction->find('css', sprintf('[id$="%s_amount"]', $channel->getCode()))->setValue($discount);
- }
-
- public function getFieldValueInLocale(string $field, string $localeCode): string
- {
- return $this->getElement($field, ['%localeCode%' => $localeCode])->getValue();
+ $lastAction->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->fillField($option, $value);
}
public function getLastScopeCodes(): array
{
$lastScope = $this->getElement('last_scope');
- return explode(',', $lastScope->find('css', 'input[type="hidden"]')->getValue());
+ return array_map(
+ fn (NodeElement $element) => $element->getValue(),
+ $lastScope->findAll('css', 'option[selected="selected"]'),
+ );
}
- public function getLastActionDiscount(): string
+ public function getLastActionOption(string $option): string
{
$lastAction = $this->getElement('last_action');
- return $lastAction->find('css', 'input')->getValue();
+ return $lastAction->findField($option)->getValue();
}
- public function getLastActionFixedDiscount(ChannelInterface $channel): string
+ public function getLastActionOptionForChannel(string $channelCode, string $option): string
{
$lastAction = $this->getElement('last_action');
- TabsHelper::switchTab($this->getSession(), $lastAction, $channel->getCode());
+ TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
- return $lastAction->find('css', sprintf('[id$="%s_amount"]', $channel->getCode()))->getValue();
+ return $lastAction->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->findField($option)->getValue();
}
- public function getValidationMessage(): string
+ public function checkIfScopeConfigurationFormIsVisible(): bool
{
- $foundElement = $this->getDocument()->find('css', '.sylius-validation-error');
-
- if (null === $foundElement) {
- throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
- }
-
- return $foundElement->getText();
+ return $this->hasElement('last_scope');
}
- public function hasValidationMessage(string $message): bool
+ public function checkIfActionConfigurationFormIsVisible(): bool
{
- $validationElements = $this->getDocument()->findAll('css', '.sylius-validation-error');
-
- foreach ($validationElements as $validationElement) {
- if ($validationElement->getText() === $message) {
- return true;
- }
- }
-
- return false;
+ return $this->hasElement('last_action');
}
- public function hasOnlyOneValidationMessage(string $message): bool
+ public function getFieldValueInLocale(string $field, string $localeCode): string
{
- $validationElements = $this->getDocument()->findAll('css', '.sylius-validation-error');
-
- $counter = 0;
- foreach ($validationElements as $validationElement) {
- if ($validationElement->getText() === $message) {
- ++$counter;
- }
- }
-
- return $counter === 1;
+ return $this->getElement($field, ['%locale_code%' => $localeCode])->getValue();
}
- public function removeAllActions(): void
+ public function getValidationMessages(): array
{
- $deleteButtons = $this->getDocument()->findAll('css', '#actions [data-form-collection="delete"]');
+ $errors = $this->getElement('form')->findAll('css', '.alert-danger');
- foreach ($deleteButtons as $deleteButton) {
- $deleteButton->click();
- }
+ return array_map(fn (NodeElement $element) => $element->getText(), $errors);
}
- public function removeAllScopes(): void
+ public function removeScopeOption(array $values): void
{
- $deleteButtons = $this->getDocument()->findAll('css', '#scopes [data-form-collection="delete"]');
-
- foreach ($deleteButtons as $deleteButton) {
- $deleteButton->click();
+ $lastScope = $this->getElement('last_scope');
+ foreach ($values as $value) {
+ $this->autocompleteHelper->removeByValue(
+ $this->getDriver(),
+ $lastScope->find('css', 'select')->getXpath(),
+ $value,
+ );
}
+
+ $this->waitForFormUpdate();
+ }
+
+ public function removeLastAction(): void
+ {
+ $this->getElement('last_action')->find('css', '[data-test-delete-action]')->click();
+ }
+
+ public function removeLastScope(): void
+ {
+ $this->getElement('last_scope')->find('css', '[data-test-delete-action]')->click();
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'actions' => '#actions',
- 'add_action_button' => '#actions [data-form-collection="add"]',
- 'add_scope_button' => '#scopes [data-form-collection="add"]',
- 'description' => '#sylius_catalog_promotion_translations_%localeCode%_description',
+ 'add_action_button' => '[data-test-actions] [data-test-add-%type%]',
+ 'add_scope_button' => '[data-test-scopes] [data-test-add-%type%]',
+ 'channels' => '#sylius_catalog_promotion_channels',
+ 'description' => '[name="sylius_catalog_promotion[translations][%locale_code%][description]"]',
'enabled' => '#sylius_catalog_promotion_enabled',
+ 'end_date_date' => '#sylius_catalog_promotion_endDate_date',
+ 'end_date_time' => '#sylius_catalog_promotion_endDate_time',
'exclusive' => '#sylius_catalog_promotion_exclusive',
- 'end_date' => '#sylius_catalog_promotion_endDate_date',
- 'label' => '#sylius_catalog_promotion_translations_%localeCode%_label',
- 'last_action' => '#actions [data-form-collection="item"]:last-child',
- 'last_scope' => '#scopes [data-form-collection="item"]:last-child',
+ 'form' => '[data-live-name-value="sylius_admin:catalog_promotion:form"]',
+ 'label' => '[name="sylius_catalog_promotion[translations][%locale_code%][label]"]',
+ 'last_action' => '[data-test-actions] [data-test-entry-row]:last-child',
+ 'last_scope' => '[data-test-scopes] [data-test-entry-row]:last-child',
'name' => '#sylius_catalog_promotion_name',
'priority' => '#sylius_catalog_promotion_priority',
- 'scopes' => '#scopes',
- 'start_date' => '#sylius_catalog_promotion_startDate_date',
+ 'start_date_date' => '#sylius_catalog_promotion_startDate_date',
+ 'start_date_time' => '#sylius_catalog_promotion_startDate_time',
]);
}
-
- private function addCollectionElement(string $collectionElement, string $buttonElement): void
- {
- $count = count($this->getCollectionItems($collectionElement));
-
- $this->getElement($buttonElement)->click();
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems($collectionElement)));
- }
-
- /** @return NodeElement[] */
- private function getCollectionItems(string $collection): array
- {
- $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]');
-
- Assert::isArray($items);
-
- return $items;
- }
}
diff --git a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php
index de218c0ecd..c2a02f4040 100644
--- a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php
+++ b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php
@@ -13,9 +13,9 @@ declare(strict_types=1);
namespace Sylius\Behat\Element\Admin\CatalogPromotion;
-use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface;
-interface FormElementInterface
+interface FormElementInterface extends BaseFormElementInterface
{
public function nameIt(string $name): void;
@@ -37,33 +37,33 @@ interface FormElementInterface
public function specifyEndDate(\DateTimeInterface $endDate): void;
- public function addScope(): void;
+ public function addScope(string $type): void;
- public function addAction(): void;
+ public function addAction(string $type): void;
- public function chooseScopeType(string $type): void;
+ public function selectScopeOption(array $values): void;
- public function chooseActionType(string $type): void;
+ public function fillActionOption(string $option, string $value): void;
- public function chooseLastScopeCodes(array $codes): void;
-
- public function specifyLastActionDiscount(string $discount): void;
-
- public function specifyLastActionDiscountForChannel(string $discount, ChannelInterface $channel): void;
-
- public function getFieldValueInLocale(string $field, string $localeCode): string;
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void;
public function getLastScopeCodes(): array;
- public function getLastActionDiscount(): string;
+ public function getLastActionOption(string $option): string;
- public function getLastActionFixedDiscount(ChannelInterface $channel): string;
+ public function getLastActionOptionForChannel(string $channelCode, string $option): string;
- public function getValidationMessage(): string;
+ public function getFieldValueInLocale(string $field, string $localeCode): string;
- public function hasValidationMessage(string $message): bool;
+ public function checkIfScopeConfigurationFormIsVisible(): bool;
- public function removeAllActions(): void;
+ public function checkIfActionConfigurationFormIsVisible(): bool;
- public function removeAllScopes(): void;
+ public function getValidationMessages(): array;
+
+ public function removeScopeOption(array $values): void;
+
+ public function removeLastAction(): void;
+
+ public function removeLastScope(): void;
}
diff --git a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php
index 88db93d230..fa8399fc1d 100644
--- a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php
+++ b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php
@@ -13,37 +13,59 @@ declare(strict_types=1);
namespace Sylius\Behat\Element\Admin\Channel;
-use FriendsOfBehat\PageObjectExtension\Element\Element;
-use Sylius\Behat\Service\AutocompleteHelper;
+use Behat\Mink\Session;
+use FriendsOfBehat\SymfonyExtension\Mink\MinkParameters;
+use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Component\Core\Model\TaxonInterface;
-final class ExcludeTaxonsFromShowingLowestPriceInputElement extends Element implements ExcludeTaxonsFromShowingLowestPriceInputElementInterface
+final class ExcludeTaxonsFromShowingLowestPriceInputElement extends BaseFormElement implements ExcludeTaxonsFromShowingLowestPriceInputElementInterface
{
+ public function __construct(
+ Session $session,
+ array|MinkParameters $minkParameters,
+ private AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters);
+ }
+
public function excludeTaxon(TaxonInterface $taxon): void
{
- $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price')->getParent();
+ $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price');
- AutocompleteHelper::chooseValue($this->getSession(), $excludeTaxonElement, $taxon->getName());
+ $this->autocompleteHelper->selectByValue(
+ $this->getDriver(),
+ $excludeTaxonElement->getXpath(),
+ $taxon->getCode(),
+ );
+ $this->waitForFormUpdate();
}
public function removeExcludedTaxon(TaxonInterface $taxon): void
{
- $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price')->getParent();
+ $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price');
- AutocompleteHelper::removeValue($this->getSession(), $excludeTaxonElement, $taxon->getName());
+ $this->autocompleteHelper->removeByValue(
+ $this->getDriver(),
+ $excludeTaxonElement->getXpath(),
+ $taxon->getCode(),
+ );
+ $this->waitForFormUpdate();
}
public function hasTaxonExcluded(TaxonInterface $taxon): bool
{
- $excludedTaxons = $this->getElement('taxons_excluded_from_showing_lowest_price')->getValue();
-
- return str_contains($excludedTaxons, $taxon->getCode());
+ return null !== $this
+ ->getElement('taxons_excluded_from_showing_lowest_price')
+ ->find('css', sprintf('option:selected:contains("%s")', $taxon->getName()))
+ ;
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'taxons_excluded_from_showing_lowest_price' => '#sylius_channel_channelPriceHistoryConfig_taxonsExcludedFromShowingLowestPrice',
+ 'form' => 'form',
+ 'taxons_excluded_from_showing_lowest_price' => '[data-test-taxons-excluded-from-showing-lowest-price]',
]);
}
}
diff --git a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php
index 06651abd80..865999e622 100644
--- a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php
+++ b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php
@@ -21,5 +21,5 @@ interface ExcludeTaxonsFromShowingLowestPriceInputElementInterface
public function removeExcludedTaxon(TaxonInterface $taxon): void;
- public function hasTaxonExcluded(TaxonInterface $taxons): bool;
+ public function hasTaxonExcluded(TaxonInterface $taxon): bool;
}
diff --git a/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php b/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php
index ffbbb46b7c..2ef1b4a74f 100644
--- a/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php
+++ b/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php
@@ -35,7 +35,7 @@ final class LowestPriceFlagElement extends Element implements LowestPriceFlagEle
protected function getDefinedElements(): array
{
return [
- 'lowest_price_for_discounted_products_visible' => '#sylius_channel_channelPriceHistoryConfig_lowestPriceForDiscountedProductsVisible',
+ 'lowest_price_for_discounted_products_visible' => '[data-test-lowest-price-for-discounted-products-visible]',
];
}
}
diff --git a/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php b/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php
index 2746772a5d..30343137b6 100644
--- a/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php
+++ b/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php
@@ -13,49 +13,80 @@ declare(strict_types=1);
namespace Sylius\Behat\Element\Admin\Channel;
+use Behat\Mink\Element\NodeElement;
use FriendsOfBehat\PageObjectExtension\Element\Element;
+use Webmozart\Assert\Assert;
final class ShippingAddressInCheckoutRequiredElement extends Element implements ShippingAddressInCheckoutRequiredElementInterface
{
+ private const ADDRESS_TYPE_BILLING = 'billing';
+
+ private const ADDRESS_TYPE_SHIPPING = 'shipping';
+
public function requireShippingAddressInCheckout(): void
{
- $this->getElement('shipping_address_in_checkout_required')->check();
+ $this->requireAddressTypeInCheckout(self::ADDRESS_TYPE_SHIPPING);
}
public function requireBillingAddressInCheckout(): void
{
- $this->getElement('shipping_address_in_checkout_required')->uncheck();
+ $this->requireAddressTypeInCheckout(self::ADDRESS_TYPE_BILLING);
}
public function requireAddressTypeInCheckout(string $type): void
{
- if ($type === 'shipping') {
- $this->requireShippingAddressInCheckout();
-
- return;
- }
-
- $this->requireBillingAddressInCheckout();
+ $this->getChoiceForAddressType($type)->click();
}
public function isShippingAddressInCheckoutRequired(): bool
{
- return $this->getElement('shipping_address_in_checkout_required')->isChecked();
+ return self::ADDRESS_TYPE_SHIPPING === $this->getRequiredAddressTypeInCheckout();
}
public function getRequiredAddressTypeInCheckout(): string
{
- if ($this->isShippingAddressInCheckoutRequired()) {
- return 'shipping';
+ foreach ($this->getChoices() as $type => $choice) {
+ if ($choice->isChecked()) {
+ return $type;
+ }
}
- return 'billing';
+ throw new \InvalidArgumentException('No address type selected.');
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'shipping_address_in_checkout_required' => '#sylius_channel_shippingAddressInCheckoutRequired',
+ 'shipping_address_in_checkout_required' => '[data-test-shipping-address-in-checkout-required]',
]);
}
+
+ private function getChoiceForAddressType(string $type): NodeElement
+ {
+ $choices = $this->getChoices();
+ Assert::keyExists($choices, $type);
+
+ return $choices[$type];
+ }
+
+ /** @return array */
+ private function getChoices(): array
+ {
+ $element = $this->getElement('shipping_address_in_checkout_required');
+ $labelsElements = $element->findAll('css', 'label');
+
+ $choices = [];
+ foreach ($labelsElements as $labelElement) {
+ $label = strtolower($labelElement->getText());
+ foreach ([self::ADDRESS_TYPE_BILLING, self::ADDRESS_TYPE_SHIPPING] as $type) {
+ if (str_contains($label, $type)) {
+ $choices[$type] = $element->findById($labelElement->getAttribute('for'));
+
+ continue 2;
+ }
+ }
+ }
+
+ return $choices;
+ }
}
diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElement.php b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php
new file mode 100644
index 0000000000..4adc75c6c0
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php
@@ -0,0 +1,56 @@
+getFieldElement($element, $parameters);
+ if (null === $foundElement) {
+ throw new ElementNotFoundException($this->getSession(), 'Field element');
+ }
+
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
+ }
+
+ return $validationMessage->getText();
+ }
+
+ protected function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('form');
+ usleep(500000); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
+
+ /** @throws ElementNotFoundException */
+ private function getFieldElement(string $element, array $parameters): ?NodeElement
+ {
+ $element = $this->getElement($element, $parameters);
+ while (null !== $element && !$element->hasClass('field')) {
+ $element = $element->getParent();
+ }
+
+ return $element;
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php
new file mode 100644
index 0000000000..819ae4c47a
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php
@@ -0,0 +1,22 @@
+getElement('flashes_container');
+
+ if (DriverHelper::isJavascript($this->getDriver())) {
+ $flashesContainer->waitFor(5, function () use ($flashesContainer) {
+ return $flashesContainer->isVisible();
+ });
+ }
+
+ /** @var array $flashes */
+ $flashes = $flashesContainer->findAll('css', '[data-test-sylius-flash-message]');
+
+ foreach ($flashes as $flash) {
+ if (str_contains($flash->getText(), $message) && $flash->getAttribute('data-test-sylius-flash-message-type') === $type) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'flashes_container' => '[data-test-sylius-flashes-container]',
+ ]);
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php b/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php
new file mode 100644
index 0000000000..5cbdafc6c2
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php
@@ -0,0 +1,19 @@
+getElement('code')->setValue($code);
+ }
+
+ public function setName(string $name, string $localeCode): void
+ {
+ $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
+ }
+
+ protected function getCodeElement(): NodeElement
+ {
+ return $this->getElement('code');
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'code' => '[data-test-code]',
+ 'name' => '[data-test-name="%locale%"]',
+ ]);
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php
new file mode 100644
index 0000000000..4eff5afcee
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php
@@ -0,0 +1,25 @@
+getElement('priority')->getValue();
+ }
+
+ public function setPriority(?int $priority): void
{
$this->getElement('priority')->setValue($priority);
}
+ public function setStartsAt(\DateTimeInterface $dateTime): void
+ {
+ $timestamp = $dateTime->getTimestamp();
+
+ $this->getElement('starts_at_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('starts_at_time')->setValue(date('H:i', $timestamp));
+ }
+
+ public function setEndsAt(\DateTimeInterface $dateTime): void
+ {
+ $timestamp = $dateTime->getTimestamp();
+
+ $this->getElement('ends_at_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('ends_at_time')->setValue(date('H:i', $timestamp));
+ }
+
+ public function setUsageLimit(int $limit): void
+ {
+ $this->getElement('usage_limit')->setValue($limit);
+ }
+
+ public function makeExclusive(): void
+ {
+ $this->getElement('exclusive')->check();
+ }
+
+ public function makeNotAppliesToDiscountedItem(): void
+ {
+ $this->getElement('applies_to_discounted')->uncheck();
+ }
+
+ public function makeCouponBased(): void
+ {
+ $this->getElement('coupon_based')->check();
+ }
+
+ public function checkChannel(string $name): void
+ {
+ $this->getElement('channels')->checkField($name);
+ }
+
+ public function setLabel(string $label, string $localeCode): void
+ {
+ $this->getElement('label', ['%locale_code%' => $localeCode])->setValue($label);
+ }
+
+ public function hasLabel(string $label, string $localeCode): bool
+ {
+ return $label === $this->getElement('label', ['%locale_code%' => $localeCode])->getValue();
+ }
+
+ public function addAction(string $type): void
+ {
+ $this->getElement('add_action_button', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function removeLastAction(): void
+ {
+ $this->getLastAction()->find('css', 'button[data-test-delete]')->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function fillActionOption(string $option, string $value): void
+ {
+ $this->getLastAction()->fillField($option, $value);
+ }
+
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void
+ {
+ $lastAction = $this->getChannelConfigurationOfLastAction($channelCode);
+ $lastAction->fillField($option, $value);
+ }
+
+ public function selectActionOption(string $option, string $value, bool $multiple = false): void
+ {
+ $this->getLastAction()->find('named', ['select', $option])->selectOption($value, $multiple);
+ }
+
+ public function addRule(string $type): void
+ {
+ $this->getElement('add_rule_button', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function removeLastRule(): void
+ {
+ $this->getLastRule()->find('css', 'button[data-test-delete]')->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function selectRuleOption(string $option, string $value, bool $multiple = false): void
+ {
+ $this->getLastRule()->find('named', ['select', $option])->selectOption($value, $multiple);
+ }
+
+ public function fillRuleOption(string $option, string $value): void
+ {
+ $this->getLastRule()->fillField($option, $value);
+ }
+
+ public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void
+ {
+ $lastRule = $this->getChannelConfigurationOfLastRule($channelCode);
+ $lastRule->fillField($option, $value);
+ }
+
+ public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void
+ {
+ $count = count($this->getElement('rules')->findAll('css', '[data-test-entry-row]'));
+ $locator = $channelCode ?
+ sprintf('#sylius_promotion_rules_%d_configuration_%s select', $count - 1, $channelCode) :
+ sprintf('#sylius_promotion_rules_%d_configuration select', $count - 1)
+ ;
+ foreach ($values as $value) {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getLastRule()->find('css', $locator)->getXpath(),
+ $value,
+ );
+ }
+
+ $this->waitForFormUpdate();
+ }
+
+ public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void
+ {
+ $count = count($this->getElement('actions')->findAll('css', '[data-test-entry-row]'));
+ $locator = sprintf('#sylius_promotion_actions_%d_configuration_%s_filters_%s_filter select', $count - 1, $channelCode, $filterType);
+ foreach ($values as $value) {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getLastAction()->find('css', $locator)->getXpath(),
+ $value,
+ );
+ }
+
+ $this->waitForFormUpdate();
+ }
+
+ public function checkIfRuleConfigurationFormIsVisible(): bool
+ {
+ return $this->hasElement('rule_count');
+ }
+
+ public function checkIfActionConfigurationFormIsVisible(): bool
+ {
+ return $this->hasElement('action_amount');
+ }
+
+ public function getValidationMessageForAction(): string
+ {
+ $actionForm = $this->getLastAction();
+
+ $foundElement = $actionForm->find('css', '.invalid-feedback');
+ if (null === $foundElement) {
+ throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.invalid-feedback');
+ }
+
+ return $foundElement->getText();
+ }
+
+ public function getValidationMessageForTranslation(string $element, string $localeCode): string
+ {
+ $foundElement = $this->getElement($element, ['%locale_code%' => $localeCode])->getParent();
+
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
+ }
+
+ return $validationMessage->getText();
+ }
+
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
+ 'action_amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount',
+ 'actions' => '#sylius_promotion_actions',
+ 'add_action_button' => '[data-test-actions] [data-test-add-%type%]',
+ 'add_rule_button' => '[data-test-rules] [data-test-add-%type%]',
+ 'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted',
+ 'channels' => '#sylius_promotion_channels',
+ 'code' => '#sylius_promotion_code',
+ 'coupon_based' => '#sylius_promotion_couponBased',
+ 'ends_at_date' => '#sylius_promotion_endsAt_date',
+ 'ends_at_time' => '#sylius_promotion_endsAt_time',
+ 'exclusive' => '#sylius_promotion_exclusive',
+ 'form' => '[data-live-name-value="sylius_admin:promotion:form"]',
+ 'label' => '[name="sylius_promotion[translations][%locale_code%][label]"]',
+ 'last_action' => '[data-test-actions] [data-test-entry-row]:last-child',
+ 'last_rule' => '[data-test-rules] [data-test-entry-row]:last-child',
+ 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min',
+ 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max',
+ 'name' => '#sylius_promotion_name',
'priority' => '#sylius_promotion_priority',
+ 'rule_count' => '#sylius_promotion_rules_0_configuration_count',
+ 'rules' => '#sylius_promotion_rules',
+ 'starts_at_date' => '#sylius_promotion_startsAt_date',
+ 'starts_at_time' => '#sylius_promotion_startsAt_time',
+ 'translation_tab' => '[data-test-promotion-translations-accordion="%locale_code%"]',
+ 'usage_limit' => '#sylius_promotion_usageLimit',
]);
}
+
+ private function getLastAction(): NodeElement
+ {
+ return $this->getElement('last_action');
+ }
+
+ private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement
+ {
+ $lastAction = $this->getLastAction();
+
+ TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
+
+ return $lastAction
+ ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode))
+ ;
+ }
+
+ private function getLastRule(): NodeElement
+ {
+ return $this->getElement('last_rule');
+ }
+
+ private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement
+ {
+ $lastRule = $this->getLastRule();
+
+ TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode);
+
+ return $lastRule->find(
+ 'css',
+ sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode),
+ );
+ }
}
diff --git a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
index 55c792c454..f7076bee1b 100644
--- a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
+++ b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php
@@ -13,7 +13,61 @@ declare(strict_types=1);
namespace Sylius\Behat\Element\Admin\Promotion;
-interface FormElementInterface
+use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface;
+
+interface FormElementInterface extends BaseFormElementInterface
{
- public function prioritizeIt(?int $priority): void;
+ public function setPriority(?int $priority): void;
+
+ public function getPriority(): int;
+
+ public function setStartsAt(\DateTimeInterface $dateTime): void;
+
+ public function setEndsAt(\DateTimeInterface $dateTime): void;
+
+ public function setUsageLimit(int $limit): void;
+
+ public function makeExclusive(): void;
+
+ public function makeNotAppliesToDiscountedItem(): void;
+
+ public function makeCouponBased(): void;
+
+ public function checkChannel(string $name): void;
+
+ public function setLabel(string $label, string $localeCode): void;
+
+ public function hasLabel(string $label, string $localeCode): bool;
+
+ public function addAction(string $type): void;
+
+ public function removeLastAction(): void;
+
+ public function fillActionOption(string $option, string $value): void;
+
+ public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void;
+
+ public function selectActionOption(string $option, string $value, bool $multiple = false): void;
+
+ public function addRule(string $type): void;
+
+ public function removeLastRule(): void;
+
+ public function selectRuleOption(string $option, string $value, bool $multiple = false): void;
+
+ public function fillRuleOption(string $option, string $value): void;
+
+ public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void;
+
+ public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void;
+
+ public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void;
+
+ public function checkIfRuleConfigurationFormIsVisible(): bool;
+
+ public function checkIfActionConfigurationFormIsVisible(): bool;
+
+ public function getValidationMessageForAction(): string;
+
+ public function getValidationMessageForTranslation(string $element, string $localeCode): string;
}
diff --git a/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php
new file mode 100644
index 0000000000..c3e4f77f71
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php
@@ -0,0 +1,179 @@
+getElement('code')->getValue();
+ }
+
+ public function setCode(string $code): void
+ {
+ $this->getElement('code')->setValue($code);
+ }
+
+ public function isCodeDisabled(): bool
+ {
+ return $this->getElement('code')->hasAttribute('disabled');
+ }
+
+ public function getName(string $localeCode = 'en_US')
+ {
+ return $this->getElement('name', ['%localeCode%' => $localeCode])->getValue();
+ }
+
+ public function setName(string $name, string $localeCode = 'en_US'): void
+ {
+ $this->getElement('name', ['%localeCode%' => $localeCode])->setValue($name);
+ }
+
+ public function getPosition(): int
+ {
+ return (int) $this->getElement('position')->getValue();
+ }
+
+ public function setPosition(int $position): void
+ {
+ $this->getElement('position')->setValue($position);
+ }
+
+ public function getDescription(string $localeCode = 'en_US'): string
+ {
+ return $this->getElement('description', ['%localeCode%' => $localeCode])->getValue();
+ }
+
+ public function setDescription(string $description, string $localeCode = 'en_US'): void
+ {
+ $this->getElement('description', ['%localeCode%' => $localeCode])->setValue($description);
+ }
+
+ public function getZoneCode(): string
+ {
+ return $this->getElement('zone')->getValue();
+ }
+
+ public function setZoneCode(string $code): void
+ {
+ $this->getElement('zone')->setValue($code);
+ }
+
+ public function disable(): void
+ {
+ $this->getElement('enabled')->uncheck();
+ }
+
+ public function enable(): void
+ {
+ $this->getElement('enabled')->check();
+ }
+
+ public function checkChannel(string $channelCode): void
+ {
+ $this->getElement('channel', ['%channelCode%' => $channelCode])->check();
+ }
+
+ public function hasCheckedChannel(string $channelCode): bool
+ {
+ return $this->getElement('channel', ['%channelCode%' => $channelCode])->isChecked();
+ }
+
+ public function setCalculatorConfigurationAmountForChannel(string $channelCode, ?int $amount): void
+ {
+ $this->selectCalculatorConfigurationChannelTab($channelCode);
+
+ $this->getElement('calculator_configuration_amount', ['%channelCode%' => $channelCode])->setValue((string) $amount);
+ }
+
+ public function chooseCalculator(string $calculatorName): void
+ {
+ $this->getElement('calculator')->selectOption($calculatorName);
+ $this->waitForFormUpdate();
+ }
+
+ public function addRule(string $type): void
+ {
+ $this->getElement('add_rule_button', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function fillLastRuleOption(string $fieldName, string $value): void
+ {
+ $lastRule = $this->getElement('last_rule');
+
+ $lastRule->fillField($fieldName, $value);
+ }
+
+ public function fillLastRuleOptionForChannel(string $channelCode, string $fieldName, string $value): void
+ {
+ $lastRule = $this->getElement('last_rule');
+
+ TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode);
+
+ $lastRule->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->fillField($fieldName, $value);
+ }
+
+ public function getShippingChargesValidationErrorsCount(string $channelCode): int
+ {
+ return count(
+ $this
+ ->getElement('calculator_configuration_channel_tab_content', ['%channelCode%' => $channelCode])
+ ->findAll('css', '.invalid-feedback'),
+ );
+ }
+
+ public function setField(string $field, string $value): void
+ {
+ $this->getDocument()->fillField($field, $value);
+ }
+
+ /**
+ * @return array
+ */
+ protected function getDefinedElements(): array
+ {
+ return [
+ 'add_rule_button' => '[data-test-rules] [data-test-add-%type%]',
+ 'calculator' => '#sylius_shipping_method_calculator',
+ 'calculator_configuration_amount' => '#sylius_shipping_method_configuration_%channelCode%_amount',
+ 'calculator_configuration_channel_tab' => '[data-test-calculator-configuration] [data-test-channel-tab="%channelCode%"]',
+ 'calculator_configuration_channel_tab_content' => '[data-test-calculator-configuration] [data-test-channel-tab-content="%channelCode%"]',
+ 'channel' => '[name="sylius_shipping_method[channels][]"][value="%channelCode%"]',
+ 'code' => '#sylius_shipping_method_code',
+ 'description' => '#sylius_shipping_method_translations_%localeCode%_description',
+ 'enabled' => '#sylius_shipping_method_enabled',
+ 'form' => '[data-live-name-value="sylius_admin:shipping_method:form"]',
+ 'last_rule' => '[data-test-rules] [data-test-entry-row]:last-child',
+ 'last_rule_amount' => '[data-test-rules] [data-test-entry-row]:last-child [id$="_configuration_%channelCode%_amount"]',
+ 'last_rule_weight' => '[data-test-rules] [data-test-entry-row]:last-child [id$="_configuration_weight"]',
+ 'name' => '#sylius_shipping_method_translations_%localeCode%_name',
+ 'position' => '#sylius_shipping_method_position',
+ 'zone' => '#sylius_shipping_method_zone',
+ ];
+ }
+
+ private function selectCalculatorConfigurationChannelTab(string $channelCode): void
+ {
+ if (!DriverHelper::isJavascript($this->getDriver())) {
+ throw new \RuntimeException('This method can be used only with JavaScript enabled');
+ }
+
+ $this->getElement('calculator_configuration_channel_tab', ['%channelCode%' => $channelCode])->click();
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php
new file mode 100644
index 0000000000..50eccb91ee
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php
@@ -0,0 +1,63 @@
+getElement('code')->getValue();
+ }
+
+ public function nameIt(string $name, string $localeCode): void
+ {
+ $this->getElement('name', ['%locale_code%' => $localeCode])->setValue($name);
+ }
+
+ public function slugIt(string $slug, string $localeCode): void
+ {
+ $this->getElement('slug', ['%locale_code%' => $localeCode])->setValue($slug);
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'code' => '[data-test-code]',
+ 'form' => '[data-live-name-value="sylius_admin:taxon:form"]',
+ 'name' => '[name="taxon[translations][%locale_code%][name]"]',
+ 'slug' => '[name="taxon[translations][%locale_code%][slug]"]',
+ ]);
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php
new file mode 100644
index 0000000000..f65fd9f766
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php
@@ -0,0 +1,25 @@
+getElement('add_image')->press();
+ $this->waitForFormUpdate();
+
+ $lastImage = $this->getElement('last_image');
+
+ if (null !== $type) {
+ $lastImage->fillField('Type', $type);
+ }
+
+ $filesPath = $this->getParameter('files_path');
+ $lastImage->find('css', '[data-test-file]')->attachFile($filesPath . $path);
+ }
+
+ public function changeImageWithType(string $type, string $path): void
+ {
+ $image = $this->getElement('image_with_type', ['%type%' => $type]);
+
+ $filesPath = $this->getParameter('files_path');
+ $image->find('css', '[data-test-file]')->attachFile($filesPath . $path);
+ }
+
+ public function modifyFirstImageType(string $type): void
+ {
+ $this->getElement('first_image')->fillField('Type', $type);
+ }
+
+ public function removeImageWithType(string $type): void
+ {
+ $this->getElement('delete_image', ['%type%' => $type])->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function removeFirstImage(): void
+ {
+ $this->getElement('first_image')->find('css', '[data-test-delete-image]')->press();
+ $this->waitForFormUpdate();
+ }
+
+ public function isImageWithTypeDisplayed(string $type): bool
+ {
+ try {
+ $image = $this->getElement('image_with_type', ['%type%' => $type]);
+ } catch (ElementNotFoundException) {
+ return false;
+ }
+
+ $imageUrl = $image->getAttribute('data-test-image-url');
+ $this->getDriver()->visit($imageUrl);
+ $statusCode = $this->getDriver()->getStatusCode();
+ $this->getDriver()->back();
+
+ return in_array($statusCode, [200, 304], true);
+ }
+
+ public function countImages(): int
+ {
+ return count($this->getElement('images')->findAll('css', '[data-test-image]'));
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'add_image' => '[data-test-images] [data-test-add-image]',
+ 'delete_image' => '[data-test-images] [data-test-image][data-test-type="%type%"] [data-test-delete-image]',
+ 'first_image' => '[data-test-images] [data-test-image]:first-child',
+ 'form' => '[data-live-name-value="sylius_admin:taxon:form"]',
+ 'image_with_type' => '[data-test-images] [data-test-image][data-test-type="%type%"]',
+ 'images' => '[data-test-images]',
+ 'last_image' => '[data-test-images] [data-test-image]:last-child',
+ ]);
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php b/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php
new file mode 100644
index 0000000000..8047a3fa12
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php
@@ -0,0 +1,33 @@
+getDocument()->find('css', 'i.ui.avatar.user.icon');
-
- return $avatarElement !== null;
+ return $this->getAvatarImagePath() === '';
}
private function getAvatarImagePath(): string
{
- $image = $this->getDocument()->find('css', 'img.ui.avatar.image');
+ $userAvatar = $this->getElement('user_avatar');
- if (null === $image) {
- return '';
- }
+ return $userAvatar->getAttribute('data-test-user-avatar');
+ }
- return $image->getAttribute('src');
+ /**
+ * @return array
+ */
+ protected function getDefinedElements(): array
+ {
+ return [
+ 'user_avatar' => '[data-test-user-avatar]',
+ ];
}
}
diff --git a/src/Sylius/Behat/Element/Admin/Zone/FormElement.php b/src/Sylius/Behat/Element/Admin/Zone/FormElement.php
new file mode 100644
index 0000000000..80d800190b
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Zone/FormElement.php
@@ -0,0 +1,125 @@
+getElement('name')->getValue();
+ }
+
+ public function getType(): string
+ {
+ return $this->getElement('type')->getValue();
+ }
+
+ public function isTypeFieldDisabled(): bool
+ {
+ return $this->getElement('type')->hasAttribute('disabled');
+ }
+
+ public function getScope(): string
+ {
+ return $this->getElement('scope')->getValue();
+ }
+
+ public function selectScope(string $scope): void
+ {
+ $this->getDocument()->selectFieldOption('Scope', $scope);
+ }
+
+ public function hasMember(string $member): bool
+ {
+ return $this->hasElement('zone_member', ['%name%' => $member]);
+ }
+
+ public function countMembers(): int
+ {
+ return count($this->getElement('zone_members')->findAll('css', '[data-test-zone-member]'));
+ }
+
+ public function addMember(): void
+ {
+ $this->getElement('add_member')->click();
+ $this->waitForElement(5, 'zone_member_added');
+ }
+
+ public function removeMember(string $member): void
+ {
+ $this->getElement('zone_member_delete', ['%name%' => $member])->click();
+ $this->waitForElement(5, 'zone_member', ['%name%' => $member], false);
+ }
+
+ public function chooseMember(string $name): void
+ {
+ $select = $this->getElement('zone_member_last')->find('css', 'select');
+ if (null === $select) {
+ throw new ElementNotFoundException($this->getSession(), 'select', 'css', 'select');
+ }
+
+ $select->selectOption($name);
+ }
+
+ public function getFormValidationMessage(): string
+ {
+ return $this->getElement('form_validation_message')->getText();
+ }
+
+ protected function getCodeElement(): NodeElement
+ {
+ return $this->getElement('code');
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'add_member' => '[data-test-add-member]',
+ 'code' => '[data-test-code]',
+ 'form' => 'form',
+ 'form_validation_message' => 'form > div.alert.alert-danger.d-block',
+ 'name' => '[data-test-name]',
+ 'scope' => '[data-test-scope]',
+ 'type' => '[data-test-type]',
+ 'zone_member' => '[data-test-zone-member]:contains("%name%")',
+ 'zone_member_added' => '[data-test-zone-member]:last-child option:not([selected="selected"])',
+ 'zone_member_delete' => '[data-test-zone-member]:contains("%name%") button[name$="[delete]"]',
+ 'zone_member_last' => '[data-test-members]:last-child',
+ 'zone_members' => '[data-test-members]',
+ ]);
+ }
+
+ private function waitForElement(
+ int $timeout,
+ string $elementName,
+ array $parameters = [],
+ bool $shouldExist = true,
+ ): bool {
+ return $this->getDocument()->waitFor(
+ $timeout,
+ fn (): bool => $shouldExist && $this->hasElement($elementName, $parameters),
+ );
+ }
+}
diff --git a/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php
new file mode 100644
index 0000000000..2acde67b17
--- /dev/null
+++ b/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php
@@ -0,0 +1,47 @@
+getChannelPriceRow($channelName);
+ $channelPriceRow = $this->getSimpleProductPricingRowForChannel($channelName);
if (null === $channelPriceRow) {
throw new \InvalidArgumentException(sprintf('Channel "%s" does not exist', $channelName));
@@ -84,8 +84,8 @@ final class PricingElement extends Element implements PricingElementInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'simple_product_pricing_row' => '#pricing tr:contains("%channelName%")',
- 'variant_pricing_row' => 'tr:contains("%variantName%") + tr:contains("%channelName%")',
+ 'simple_product_pricing_row' => '[data-test-simple-product="%channelName%"]',
+ 'variant_pricing_row' => '[data-test-variants="%channelName%.%variantName%"]',
]);
}
diff --git a/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php b/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php
index ef7540695e..4d6ff61a7c 100644
--- a/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php
+++ b/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php
@@ -74,19 +74,11 @@ final class VariantsElement extends Element implements VariantsElementInterface
string $lowestPriceBeforeDiscount,
string $channelName,
): bool {
- /** @var NodeElement[] $variantRows */
- $variantRows = $this->getDocument()->findAll('css', '#variants .variants-accordion__title');
-
/** @var NodeElement $variant */
- foreach ($variantRows as $variant) {
- if ($this->isVariantWithLowestPriceBeforeDiscountInChannel(
- $variant,
- $productVariantName,
- $lowestPriceBeforeDiscount,
- $channelName,
- )) {
- return true;
- }
+ $variant = $this->getDocument()->find('css', sprintf('[data-test-lowest-price-before-the-discount="%s.%s"]', $productVariantName, $channelName));
+
+ if ($variant) {
+ return $variant->getText() === $lowestPriceBeforeDiscount;
}
return false;
@@ -117,46 +109,8 @@ final class VariantsElement extends Element implements VariantsElementInterface
return false;
}
- private function isVariantWithLowestPriceBeforeDiscountInChannel(
- NodeElement $variant,
- string $name,
- string $lowestPriceBeforeDiscount,
- string $channel,
- ): bool {
- $variantContent = $variant->getParent()->find(
- 'css',
- sprintf('.variants-accordion__content.%s', $this->getItemIndexClass($variant)),
- );
-
- $headerRow = $variantContent->find('css', '.pricing-header');
- $lowestPriceColumnIndex = $this->getLowestPriceColumnIndex($headerRow);
-
- if ($lowestPriceColumnIndex === null) {
- return false;
- }
-
- return
- $variant->find('css', '.content .variant-name')->getText() === $name &&
- $variantContent->find(
- 'css',
- sprintf('tr.pricing:contains("%s") td:nth-child(%s)', $channel, $lowestPriceColumnIndex),
- )->getText() === $lowestPriceBeforeDiscount
- ;
- }
-
private function getItemIndexClass(NodeElement $variant): string
{
return explode(' ', $variant->getAttribute('class'))[1];
}
-
- private function getLowestPriceColumnIndex(NodeElement $headerRow): ?int
- {
- foreach ($headerRow->findAll('css', 'td') as $index => $cell) {
- if ($cell->getText() === 'Lowest price before discount') {
- return $index + 1;
- }
- }
-
- return null;
- }
}
diff --git a/src/Sylius/Behat/NotificationType.php b/src/Sylius/Behat/NotificationType.php
index 9a38a8b9ef..0400bd0508 100644
--- a/src/Sylius/Behat/NotificationType.php
+++ b/src/Sylius/Behat/NotificationType.php
@@ -26,11 +26,21 @@ final class NotificationType implements \Stringable
return $this->value;
}
+ /**
+ * @deprecated Use ::error() instead
+ *
+ * @todo remove and replace all usages with ::error() in 2.0
+ */
public static function failure(): self
{
return static::getTyped('failure');
}
+ public static function error(): self
+ {
+ return static::getTyped('error');
+ }
+
public static function success(): self
{
return static::getTyped('success');
diff --git a/src/Sylius/Behat/Page/Admin/Account/LoginPage.php b/src/Sylius/Behat/Page/Admin/Account/LoginPage.php
index f59b337bfb..6fff88db8a 100644
--- a/src/Sylius/Behat/Page/Admin/Account/LoginPage.php
+++ b/src/Sylius/Behat/Page/Admin/Account/LoginPage.php
@@ -45,7 +45,7 @@ class LoginPage extends SymfonyPage implements LoginPageInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'validation_error' => '.message.negative',
+ 'validation_error' => '[data-test-invalid-credentials-message]',
]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php b/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php
index 14879e0b8a..1e051e29c6 100644
--- a/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php
@@ -17,66 +17,10 @@ use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
- public function isAvatarAttached(): bool
- {
- return $this->getElement('add_avatar')->has('css', 'img');
- }
-
- public function attachAvatar(string $path): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $imageForm = $this->getElement('add_avatar')->find('css', 'input[type="file"]');
-
- $imageForm->attachFile($filesPath . $path);
- }
-
- public function enable(): void
- {
- $this->getElement('enabled')->check();
- }
-
- public function specifyUsername(string $username): void
- {
- $this->getElement('name')->setValue($username);
- }
-
- public function specifyEmail(string $email): void
- {
- $this->getElement('email')->setValue($email);
- }
-
- public function specifyFirstName(string $firstName): void
- {
- $this->getElement('first_name')->setValue($firstName);
- }
-
- public function specifyLastName(string $lastName): void
- {
- $this->getElement('last_name')->setValue($lastName);
- }
-
- public function specifyPassword(string $password): void
- {
- $this->getElement('password')->setValue($password);
- }
-
- public function specifyLocale(string $localeCode): void
- {
- $this->getElement('locale_code')->selectOption($localeCode);
- }
+ use FormAwareTrait;
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'add_avatar' => '#add-avatar',
- 'email' => '#sylius_admin_user_email',
- 'enabled' => '#sylius_admin_user_enabled',
- 'first_name' => '#sylius_admin_user_firstName',
- 'last_name' => '#sylius_admin_user_lastName',
- 'locale_code' => '#sylius_admin_user_localeCode',
- 'name' => '#sylius_admin_user_username',
- 'password' => '#sylius_admin_user_plainPassword',
- ]);
+ return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements());
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php
index e2f6f22510..4a16ea059b 100644
--- a/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php
@@ -15,23 +15,6 @@ namespace Sylius\Behat\Page\Admin\Administrator;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
-interface CreatePageInterface extends BaseCreatePageInterface
+interface CreatePageInterface extends BaseCreatePageInterface, FormAwareInterface
{
- public function isAvatarAttached(): bool;
-
- public function attachAvatar(string $path): void;
-
- public function enable(): void;
-
- public function specifyUsername(string $username): void;
-
- public function specifyEmail(string $email): void;
-
- public function specifyFirstName(string $firstName): void;
-
- public function specifyLastName(string $lastName): void;
-
- public function specifyPassword(string $password): void;
-
- public function specifyLocale(string $localeCode): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php
new file mode 100644
index 0000000000..c589f0333f
--- /dev/null
+++ b/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php
@@ -0,0 +1,51 @@
+getElement('field_first_name')->setValue($firstName);
+ }
+
+ public function getFirstName(): string
+ {
+ return $this->getElement('field_first_name')->getValue();
+ }
+
+ public function setLastName(string $lastName): void
+ {
+ $this->getElement('field_last_name')->setValue($lastName);
+ }
+
+ public function getLastName(): string
+ {
+ return $this->getElement('field_last_name')->getValue();
+ }
+
+ public function setUsername(string $username): void
+ {
+ $this->getElement('field_username')->setValue($username);
+ }
+
+ public function getUsername(): string
+ {
+ return $this->getElement('field_username')->getValue();
+ }
+
+ public function setEmail(string $email): void
+ {
+ $this->getElement('field_email')->setValue($email);
+ }
+
+ public function getEmail(): string
+ {
+ return $this->getElement('field_email')->getValue();
+ }
+
+ public function setPassword(string $password): void
+ {
+ $this->getElement('field_password')->setValue($password);
+ }
+
+ public function getPassword(): string
+ {
+ return $this->getElement('field_password')->getValue();
+ }
+
+ public function setLocale(string $locale): void
+ {
+ $this->getElement('field_locale_code')->setValue($locale);
+ }
+
+ public function getLocale(): string
+ {
+ return $this->getElement('field_locale_code')->getValue();
+ }
+
+ public function enable(): void
+ {
+ $this->getElement('field_enabled')->check();
+ }
+
+ public function disable(): void
+ {
+ $this->getElement('field_enabled')->uncheck();
+ }
+
+ public function isEnabled(): bool
+ {
+ return $this->getElement('field_enabled')->getValue();
+ }
+
+ public function isAvatarAttached(): bool
+ {
+ return $this->getElement('avatar_image')->getAttribute('data-test-avatar-image') !== '';
+ }
+
+ public function attachAvatar(string $path): void
+ {
+ $filesPath = $this->getParameter('files_path');
+ $avatarField = $this->getElement('field_avatar');
+ $avatarField->attachFile($filesPath . $path);
+ }
+
+ /**
+ * @return array
+ */
+ protected function getDefinedFormElements(): array
+ {
+ return [
+ 'avatar_image' => '[data-test-avatar-image]',
+ 'field_avatar' => '#sylius_admin_user_avatar_file',
+ 'field_email' => '#sylius_admin_user_email',
+ 'field_enabled' => '#sylius_admin_user_enabled',
+ 'field_first_name' => '#sylius_admin_user_firstName',
+ 'field_last_name' => '#sylius_admin_user_lastName',
+ 'field_locale_code' => '#sylius_admin_user_localeCode',
+ 'field_name' => '#sylius_admin_user_username',
+ 'field_password' => '#sylius_admin_user_plainPassword',
+ 'field_username' => '#sylius_admin_user_username',
+ ];
+ }
+}
diff --git a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php
index 236452ba51..b3963dcba2 100644
--- a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php
@@ -17,38 +17,11 @@ use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
{
- public function attachAvatar(string $path): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $imageForm = $this->getElement('add_avatar')->find('css', 'input[type="file"]');
-
- $imageForm->attachFile($filesPath . $path);
- }
-
- public function changeUsername(string $username): void
- {
- $this->getElement('username')->setValue($username);
- }
-
- public function changeEmail(string $email): void
- {
- $this->getElement('email')->setValue($email);
- }
-
- public function changePassword(string $password): void
- {
- $this->getElement('password')->setValue($password);
- }
-
- public function changeLocale(string $localeCode): void
- {
- $this->getElement('locale_code')->selectOption($localeCode);
- }
+ use FormAwareTrait;
public function removeAvatar(): void
{
- $this->getElement('remove_avatar')->click();
+ $this->getElement('button_delete_avatar')->click();
}
public function hasAvatar(string $avatarPath): bool
@@ -58,27 +31,28 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return str_contains($srcPath, $avatarPath);
}
+ public function changeLocale(string $localeCode): void
+ {
+ $this->getElement('locale-switch')->selectOption($localeCode);
+ }
+
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'add_avatar' => '#add-avatar',
- 'email' => '#sylius_admin_user_email',
- 'enabled' => '#sylius_admin_user_enabled',
- 'locale_code' => '#sylius_admin_user_localeCode',
- 'password' => '#sylius_admin_user_plainPassword',
- 'remove_avatar' => '.ui.icon.red.labeled.button',
- 'username' => '#sylius_admin_user_username',
+ return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements(), [
+ 'button_delete_avatar' => '[data-test-delete-avatar-button]',
+ 'locale-switch' => '[data-test-admin-locale-switch]',
]);
}
private function getAvatarImagePath(): string
{
- $image = $this->getElement('add_avatar')->find('css', 'img');
+ $avatarImage = $this->getElement('avatar_image');
+ $imagePath = $avatarImage->getAttribute('data-test-avatar-image');
- if (null === $image) {
+ if (null === $imagePath) {
return '';
}
- return $image->getAttribute('src');
+ return $imagePath;
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php
index 26854bd946..57bc9fff06 100644
--- a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php
@@ -15,19 +15,11 @@ namespace Sylius\Behat\Page\Admin\Administrator;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
-interface UpdatePageInterface extends BaseUpdatePageInterface
+interface UpdatePageInterface extends BaseUpdatePageInterface, FormAwareInterface
{
- public function attachAvatar(string $path): void;
-
- public function changeUsername(string $username): void;
-
- public function changeEmail(string $email): void;
-
- public function changePassword(string $password): void;
-
- public function changeLocale(string $localeCode): void;
-
public function removeAvatar(): void;
public function hasAvatar(string $avatarPath): bool;
+
+ public function changeLocale(string $localeCode): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php
index 773d109540..8755f105c3 100644
--- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php
@@ -20,24 +20,11 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
{
use SpecifiesItsField;
- public function checkIfScopeConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('products');
- }
-
- public function checkIfActionConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('amount');
- }
-
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'amount' => '[name^="sylius_catalog_promotion[actions][0][configuration]"][name$="[amount]"]',
'code' => '#sylius_catalog_promotion_code',
- 'endDate' => '#sylius_catalog_promotion_endDate',
'name' => '#sylius_catalog_promotion_name',
- 'products' => '[name="sylius_catalog_promotion[scopes][0][configuration][products]"]',
]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php
index ed8267f63e..67adf6cf7d 100644
--- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php
@@ -17,9 +17,5 @@ use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
- public function checkIfScopeConfigurationFormIsVisible(): bool;
-
- public function checkIfActionConfigurationFormIsVisible(): bool;
-
public function specifyCode(string $code): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php
index 1b0c205c74..9333e04b94 100644
--- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php
+++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php
@@ -47,7 +47,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasActionWithPercentageDiscount(string $amount): bool
{
- $amountsElements = $this->getDocument()->findAll('css', '[data-test-action-amount]');
+ $amountsElements = $this->getElement('actions')->findAll('css', '[data-test-action] [data-test-amount]');
foreach ($amountsElements as $amountElement) {
if ($amountElement->getText() === $amount) {
return true;
@@ -59,7 +59,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasActionWithFixedDiscount(string $amount, ChannelInterface $channel): bool
{
- $amountsElements = $this->getDocument()->findAll('css', '[data-test-action-' . $channel->getCode() . '-amount]');
+ $amountsElements = $this->getElement('actions')->findAll('css', '[data-test-' . $channel->getCode() . '-amount]');
foreach ($amountsElements as $amountElement) {
if ($amountElement->getText() === $amount) {
return true;
@@ -71,7 +71,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasScopeWithVariant(ProductVariantInterface $variant): bool
{
- $variantsElements = $this->getDocument()->findAll('css', '[data-test-scope-variants]');
+ $variantsElements = $this->getElement('scopes')->findAll('css', '[data-test-variants] li');
foreach ($variantsElements as $variantElement) {
if ($variantElement->getText() === $variant->getCode()) {
return true;
@@ -83,7 +83,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasScopeWithProduct(ProductInterface $product): bool
{
- $productsElements = $this->getDocument()->findAll('css', '[data-test-scope-products]');
+ $productsElements = $this->getElement('scopes')->findAll('css', '[data-test-products] li');
foreach ($productsElements as $productElement) {
if ($productElement->getText() === $product->getCode()) {
return true;
@@ -95,16 +95,18 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function isExclusive(): bool
{
- return $this->hasElement('exclusive');
+ return null !== $this->getElement('exclusive')->find('css', 'svg.text-green');
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
+ 'actions' => '[data-test-actions]',
'end_date' => '[data-test-end-date]',
'exclusive' => '[data-test-exclusive]',
'name' => '[data-test-name]',
'priority' => '[data-test-priority]',
+ 'scopes' => '[data-test-scopes]',
'start_date' => '[data-test-start-date]',
]);
}
diff --git a/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php b/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php
index 833ea30f23..739c065f72 100644
--- a/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php
@@ -14,12 +14,14 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Channel;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\DescribesIt;
use Sylius\Behat\Behaviour\NamesIt;
use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Behaviour\Toggles;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
-use Sylius\Behat\Service\AutocompleteHelper;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
+use Symfony\Component\Routing\RouterInterface;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
@@ -27,67 +29,21 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
use SpecifiesItsField;
use DescribesIt;
use Toggles;
+ use FormTrait;
- public function setHostname(string $hostname): void
- {
- $this->getElement('hostname')->setValue($hostname);
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
}
- public function setContactEmail(string $contactEmail): void
+ protected function getToggleableElement(): NodeElement
{
- $this->getElement('contact_email')->setValue($contactEmail);
- }
-
- public function setContactPhoneNumber(string $contactPhoneNumber): void
- {
- $this->getElement('contact_phone_number')->setValue($contactPhoneNumber);
- }
-
- public function defineColor(string $color): void
- {
- $this->getElement('color')->setValue($color);
- }
-
- public function chooseCurrency(string $currencyCode): void
- {
- $this->getDocument()->selectFieldOption('Currencies', $currencyCode);
- }
-
- public function chooseLocale(string $language): void
- {
- $this->getDocument()->selectFieldOption('Locales', $language);
- }
-
- public function chooseDefaultTaxZone(string $taxZone): void
- {
- $this->getDocument()->selectFieldOption('Default tax zone', $taxZone);
- }
-
- public function chooseDefaultLocale(?string $locale): void
- {
- if (null !== $locale) {
- $this->getElement('default_locale')->selectOption($locale);
- }
- }
-
- public function chooseOperatingCountries(array $countries): void
- {
- foreach ($countries as $country) {
- $this->getElement('countries')->selectOption($country, true);
- }
- }
-
- public function chooseBaseCurrency(?string $currency): void
- {
- if (null !== $currency) {
- $this->getElement('currencies')->selectOption($currency);
- $this->getElement('base_currency')->selectOption($currency);
- }
- }
-
- public function chooseTaxCalculationStrategy(string $taxZone): void
- {
- $this->getDocument()->selectFieldOption('Tax calculation strategy', $taxZone);
+ return $this->getElement('enabled');
}
public function allowToSkipShippingStep(): void
@@ -100,34 +56,11 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
$this->getDocument()->checkField('Skip payment step if only one payment method is available?');
}
- public function specifyMenuTaxon(string $menuTaxon): void
- {
- $menuTaxonElement = $this->getElement('menu_taxon')->getParent();
-
- AutocompleteHelper::chooseValue($this->getSession(), $menuTaxonElement, $menuTaxon);
- }
-
- protected function getToggleableElement(): NodeElement
- {
- return $this->getElement('enabled');
- }
-
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'base_currency' => '#sylius_channel_baseCurrency',
- 'code' => '#sylius_channel_code',
- 'color' => '#sylius_channel_color',
- 'contact_email' => '#sylius_channel_contactEmail',
- 'contact_phone_number' => '#sylius_channel_contactPhoneNumber',
- 'countries' => '#sylius_channel_countries',
- 'currencies' => '#sylius_channel_currencies',
- 'default_locale' => '#sylius_channel_defaultLocale',
- 'enabled' => '#sylius_channel_enabled',
- 'hostname' => '#sylius_channel_hostname',
- 'locales' => '#sylius_channel_locales',
- 'menu_taxon' => '#sylius_channel_menuTaxon',
- 'name' => '#sylius_channel_name',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ $this->getDefinedFormElements(),
+ );
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php
index 2789ef3161..513259a917 100644
--- a/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php
@@ -37,16 +37,16 @@ interface CreatePageInterface extends BaseCreatePageInterface
public function chooseLocale(string $language): void;
- public function chooseCurrency(string $currencyCode): void;
+ public function chooseCurrency(string $currencyName): void;
public function chooseDefaultTaxZone(string $taxZone): void;
- public function chooseDefaultLocale(?string $locale): void;
+ public function chooseDefaultLocale(string $locale): void;
/** @param string[] $countries */
public function chooseOperatingCountries(array $countries): void;
- public function chooseBaseCurrency(?string $currency): void;
+ public function chooseBaseCurrency(string $currency): void;
public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void;
diff --git a/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php b/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php
new file mode 100644
index 0000000000..138201da88
--- /dev/null
+++ b/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php
@@ -0,0 +1,147 @@
+ '[data-test-base-currency]',
+ 'code' => '[data-test-code]',
+ 'color' => '[data-test-color]',
+ 'contact_email' => '[data-test-contact-email]',
+ 'contact_phone_number' => '[data-test-contact-phone-number]',
+ 'countries' => '#sylius_channel_countries',
+ 'currencies' => '#sylius_channel_currencies',
+ 'default_locale' => '#sylius_channel_defaultLocale',
+ 'default_tax_zone' => '[data-test-default-tax-zone]',
+ 'discounted_products_checking_period' => '[data-test-lowest-price-for-discounted-products-checking-period]',
+ 'enabled' => '[data-test-enabled]',
+ 'form' => 'form',
+ 'hostname' => '[data-test-hostname]',
+ 'locales' => '[data-test-locales]',
+ 'menu_taxon' => '[data-test-menu-taxon]',
+ 'name' => '[data-test-name]',
+ 'tax_calculation_strategy' => '[data-test-tax-calculation-strategy]',
+ 'theme' => '[data-test-theme]',
+ ];
+ }
+
+ public function setHostname(string $hostname): void
+ {
+ $this->getElement('hostname')->setValue($hostname);
+ }
+
+ public function setTheme(string $themeName): void
+ {
+ $this->getElement('theme')->selectOption($themeName);
+ }
+
+ public function getTheme(): string
+ {
+ return $this->getElement('theme')->getValue();
+ }
+
+ public function setContactEmail(string $contactEmail): void
+ {
+ $this->getElement('contact_email')->setValue($contactEmail);
+ }
+
+ public function setContactPhoneNumber(string $contactPhoneNumber): void
+ {
+ $this->getElement('contact_phone_number')->setValue($contactPhoneNumber);
+ }
+
+ public function defineColor(string $color): void
+ {
+ $this->getElement('color')->setValue($color);
+ }
+
+ public function chooseCurrency(string $currencyName): void
+ {
+ $this->getElement('currencies')->selectOption($currencyName, true);
+ }
+
+ public function chooseLocale(string $language): void
+ {
+ $this->getElement('locales')->selectOption($language);
+ }
+
+ public function chooseDefaultTaxZone(string $taxZone): void
+ {
+ $this->getElement('default_tax_zone')->selectOption($taxZone);
+ }
+
+ public function chooseDefaultLocale(string $locale): void
+ {
+ $this->getElement('default_locale')->selectOption($locale);
+ }
+
+ public function chooseOperatingCountries(array $countries): void
+ {
+ foreach ($countries as $country) {
+ $this->getElement('countries')->selectOption($country, true);
+ }
+ }
+
+ public function chooseBaseCurrency(string $currency): void
+ {
+ $this->getElement('currencies')->selectOption($currency, true);
+ $this->getElement('base_currency')->selectOption($currency);
+ }
+
+ public function getMenuTaxon(): string
+ {
+ return $this->getSelectedOptionText('menu_taxon');
+ }
+
+ public function specifyMenuTaxon(string $menuTaxon): void
+ {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getElement('menu_taxon')->getXpath(),
+ $menuTaxon,
+ );
+ $this->waitForFormUpdate();
+ }
+
+ public function getTaxCalculationStrategy(): string
+ {
+ return $this->getSelectedOptionText('tax_calculation_strategy');
+ }
+
+ public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void
+ {
+ $this->getElement('tax_calculation_strategy')->selectOption($taxCalculationStrategy);
+ }
+
+ private function getSelectedOptionText(string $element): string
+ {
+ return $this
+ ->getElement($element)
+ ->find('css', 'option:selected')
+ ->getText()
+ ;
+ }
+
+ private function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('form');
+ sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
+}
diff --git a/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php
index 6df7d5959a..461fd38a57 100644
--- a/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php
@@ -14,74 +14,48 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Channel;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
use Sylius\Behat\Behaviour\Toggles;
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
-use Sylius\Behat\Service\AutocompleteHelper;
-use Sylius\Behat\Service\DriverHelper;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
+use Symfony\Component\Routing\RouterInterface;
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
{
use ChecksCodeImmutability;
use Toggles;
+ use FormTrait;
- public function setTheme(string $themeName): void
- {
- $this->getDocument()->selectFieldOption('Theme', $themeName);
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
}
- public function unsetTheme(): void
+ public function getLocales(): array
{
- $this->getDocument()->selectFieldOption('Theme', '');
+ return array_map(
+ fn (NodeElement $element) => $element->getText(),
+ $this->getElement('locales')->findAll('css', 'option:selected'),
+ );
}
- public function chooseLocale(string $language): void
+ public function getCurrencies(): array
{
- $this->getDocument()->selectFieldOption('Locales', $language);
+ return array_map(
+ fn (NodeElement $element) => $element->getText(),
+ $this->getElement('currencies')->findAll('css', 'option:selected'),
+ );
}
- public function chooseCurrency(string $currencyCode): void
+ public function getDefaultTaxZone(): ?string
{
- $this->getDocument()->selectFieldOption('Currencies', $currencyCode);
- }
-
- public function chooseDefaultTaxZone(string $taxZone): void
- {
- $this->getDocument()->selectFieldOption('Default tax zone', $taxZone);
- }
-
- public function chooseTaxCalculationStrategy(string $taxZone): void
- {
- $this->getDocument()->selectFieldOption('Tax calculation strategy', $taxZone);
- }
-
- public function isLocaleChosen(string $language): bool
- {
- return $this->getElement('locales')->find('named', ['option', $language])->hasAttribute('selected');
- }
-
- public function isCurrencyChosen(string $currencyCode): bool
- {
- return $this->getElement('currencies')->find('named', ['option', $currencyCode])->hasAttribute('selected');
- }
-
- public function isDefaultTaxZoneChosen(string $taxZone): bool
- {
- return $this->getElement('default_tax_zone')->find('named', ['option', $taxZone])->hasAttribute('selected');
- }
-
- public function isAnyDefaultTaxZoneChosen(): bool
- {
- return null !== $this->getElement('default_tax_zone')->find('css', '[selected]');
- }
-
- public function isTaxCalculationStrategyChosen(string $taxCalculationStrategy): bool
- {
- return $this
- ->getElement('tax_calculation_strategy')
- ->find('named', ['option', $taxCalculationStrategy])
- ->hasAttribute('selected')
- ;
+ return $this->getElement('default_tax_zone')->find('css', 'option:selected')?->getText();
}
public function isBaseCurrencyDisabled(): bool
@@ -89,31 +63,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $this->getElement('base_currency')->hasAttribute('disabled');
}
- public function changeMenuTaxon(string $menuTaxon): void
- {
- $menuTaxonElement = $this->getElement('menu_taxon')->getParent();
-
- AutocompleteHelper::chooseValue($this->getSession(), $menuTaxonElement, $menuTaxon);
- }
-
- public function getMenuTaxon(): string
- {
- $element = $this->getElement('menu_taxon');
-
- if (DriverHelper::isJavascript($this->getDriver())) {
- $this->getDocument()->waitFor(1, function () use ($element) {
- return $element->getText() !== '';
- });
- }
-
- return $element->getText();
- }
-
- public function getUsedTheme(): string
- {
- return $this->getElement('theme')->getValue();
- }
-
protected function getCodeElement(): NodeElement
{
return $this->getElement('code');
@@ -126,18 +75,9 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'base_currency' => '#sylius_channel_baseCurrency',
- 'code' => '#sylius_channel_code',
- 'currencies' => '#sylius_channel_currencies',
- 'default_locale' => '#sylius_channel_defaultLocale',
- 'default_tax_zone' => '#sylius_channel_defaultTaxZone',
- 'discounted_products_checking_period' => '#sylius_channel_channelPriceHistoryConfig_lowestPriceForDiscountedProductsCheckingPeriod',
- 'enabled' => '#sylius_channel_enabled',
- 'locales' => '#sylius_channel_locales',
- 'menu_taxon' => '#sylius_channel_menuTaxon ~ .text',
- 'name' => '#sylius_channel_name',
- 'tax_calculation_strategy' => '#sylius_channel_taxCalculationStrategy',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ $this->getDefinedFormElements(),
+ );
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php
index 235817c5be..8488d5927e 100644
--- a/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php
@@ -13,7 +13,6 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Channel;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
interface UpdatePageInterface extends BaseUpdatePageInterface
@@ -22,38 +21,33 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function disable(): void;
+ public function getTheme(): string;
+
public function setTheme(string $themeName): void;
- /**
- * @throws ElementNotFoundException
- */
- public function unsetTheme(): void;
+ /** @return string[] */
+ public function getLocales(): array;
public function chooseLocale(string $language): void;
+ /** @return string[] */
+ public function getCurrencies(): array;
+
public function chooseCurrency(string $currencyCode): void;
+ public function getDefaultTaxZone(): ?string;
+
public function chooseDefaultTaxZone(string $taxZone): void;
+ public function getTaxCalculationStrategy(): string;
+
public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void;
public function isCodeDisabled(): bool;
- public function isLocaleChosen(string $language): bool;
-
- public function isCurrencyChosen(string $currencyCode): bool;
-
- public function isDefaultTaxZoneChosen(string $taxZone): bool;
-
- public function isAnyDefaultTaxZoneChosen(): bool;
-
- public function isTaxCalculationStrategyChosen(string $taxCalculationStrategy): bool;
-
public function isBaseCurrencyDisabled(): bool;
- public function changeMenuTaxon(string $menuTaxon): void;
+ public function specifyMenuTaxon(string $menuTaxon): void;
public function getMenuTaxon(): string;
-
- public function getUsedTheme(): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/Country/CreatePage.php b/src/Sylius/Behat/Page/Admin/Country/CreatePage.php
index d6a85658ea..db60509dfd 100644
--- a/src/Sylius/Behat/Page/Admin/Country/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Country/CreatePage.php
@@ -13,43 +13,58 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Country;
-use Behat\Mink\Element\NodeElement;
-use Sylius\Behat\Behaviour\ChoosesName;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
use Webmozart\Assert\Assert;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
- use ChoosesName;
-
- public function addProvince(string $name, string $code, ?string $abbreviation = null): void
+ public function selectCountry(string $countryName): void
{
- $this->getDocument()->clickLink('Add province');
+ $this->getElement('code')->selectOption($countryName);
+ }
- $provinceForm = $this->getLastProvinceElement();
+ public function addProvince(): void
+ {
+ $count = count($this->getProvinceItems());
- $provinceForm->fillField('Name', $name);
- $provinceForm->fillField('Code', $code);
+ $this->getElement('add_province')->click();
- if (null !== $abbreviation) {
- $provinceForm->fillField('Abbreviation', $abbreviation);
- }
+ $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getProvinceItems()));
+ }
+
+ public function specifyProvinceName(string $name): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-name]')->setValue($name);
+ }
+
+ public function specifyProvinceCode(string $code): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-code]')->setValue($code);
+ }
+
+ public function specifyProvinceAbbreviation(string $abbreviation): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-abbreviation]')->setValue($abbreviation);
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'provinces' => '#sylius_country_provinces',
+ 'code' => '[data-test-code]',
+ 'provinces' => '[data-test-provinces]',
+ 'last_province' => '[data-test-provinces] [data-test-province]:last-child',
+ 'add_province' => '[data-test-add-province]',
]);
}
- private function getLastProvinceElement(): NodeElement
+ private function getProvinceItems(): array
{
- $provinces = $this->getElement('provinces');
- $items = $provinces->findAll('css', 'div[data-form-collection="item"]');
+ $items = $this->getElement('provinces')->findAll('css', '[data-test-province]');
+ Assert::isArray($items);
- Assert::notEmpty($items);
-
- return end($items);
+ return $items;
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php
index e1017850c2..45ba678c94 100644
--- a/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php
@@ -17,7 +17,13 @@ use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
- public function chooseName(string $name): void;
+ public function selectCountry(string $countryName): void;
- public function addProvince(string $name, string $code, ?string $abbreviation = null): void;
+ public function addProvince(): void;
+
+ public function specifyProvinceName(string $name): void;
+
+ public function specifyProvinceCode(string $code): void;
+
+ public function specifyProvinceAbbreviation(string $abbreviation): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/Country/IndexPage.php b/src/Sylius/Behat/Page/Admin/Country/IndexPage.php
index dc07e2458f..6d2374305f 100644
--- a/src/Sylius/Behat/Page/Admin/Country/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/Country/IndexPage.php
@@ -20,12 +20,12 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface
{
public function isCountryDisabled(CountryInterface $country): bool
{
- return $this->checkCountryStatus($country, 'Disabled');
+ return $this->checkCountryStatus($country, 'disabled');
}
public function isCountryEnabled(CountryInterface $country): bool
{
- return $this->checkCountryStatus($country, 'Enabled');
+ return $this->checkCountryStatus($country, 'enabled');
}
private function checkCountryStatus(CountryInterface $country, string $status): bool
@@ -36,6 +36,6 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface
$row = $tableAccessor->getRowWithFields($table, ['code' => $country->getCode()]);
$enabledField = $tableAccessor->getFieldFromRow($table, $row, 'enabled');
- return $enabledField->getText() === $status;
+ return $enabledField->has('css', sprintf('[data-test-status-%s]', $status));
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php
index b873b99af1..840030c3c8 100644
--- a/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php
@@ -30,6 +30,33 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $codeField->getAttribute('disabled') === 'disabled';
}
+ public function addProvince(): void
+ {
+ $count = count($this->getProvinceItems());
+
+ $this->getElement('add_province')->click();
+
+ $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getProvinceItems()));
+ }
+
+ public function specifyProvinceName(string $name): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-name]')->setValue($name);
+ }
+
+ public function specifyProvinceCode(string $code): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-code]')->setValue($code);
+ }
+
+ public function specifyProvinceAbbreviation(string $abbreviation): void
+ {
+ $province = $this->getElement('last_province');
+ $province->find('css', '[data-test-province-abbreviation]')->setValue($abbreviation);
+ }
+
public function isThereProvince(string $provinceName): bool
{
$provinces = $this->getElement('provinces');
@@ -47,78 +74,35 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
public function removeProvince(string $provinceName): void
{
if ($this->isThereProvince($provinceName)) {
- $provinces = $this->getElement('provinces');
+ $province = $this->getProvinceElement($provinceName);
- $item = $provinces
- ->find('css', sprintf('div[data-form-collection="item"] input[value="%s"]', $provinceName))
- ->getParent()
- ->getParent()
- ->getParent()
- ->getParent()
- ->getParent()
- ;
-
- $item->clickLink('Delete');
+ $province->find('css', '[data-test-delete-province]')->click();
+ $this->getDocument()->waitFor(5, fn () => !$this->isThereProvince($provinceName));
}
}
- public function addProvince(string $name, string $code, ?string $abbreviation = null): void
- {
- $this->clickAddProvinceButton();
-
- $provinceForm = $this->getLastProvinceElement();
-
- $provinceForm->fillField('Name', $name);
- $provinceForm->fillField('Code', $code);
-
- if (null !== $abbreviation) {
- $provinceForm->fillField('Abbreviation', $abbreviation);
- }
- }
-
- public function clickAddProvinceButton(): void
- {
- $this->getDocument()->clickLink('Add province');
- }
-
- public function nameProvince(string $name): void
- {
- $provinceForm = $this->getLastProvinceElement();
-
- $provinceForm->fillField('Name', $name);
- }
-
public function removeProvinceName(string $provinceName): void
{
if ($this->isThereProvince($provinceName)) {
- $provinces = $this->getElement('provinces');
-
- $item = $provinces->find('css', 'div[data-form-collection="item"] input[value="' . $provinceName . '"]')->getParent();
- $item->fillField('Name', '');
+ $province = $this->getProvinceElement($provinceName);
+ $province->find('css', '[data-test-province-name]')->setValue('');
}
}
- public function specifyProvinceCode(string $code): void
- {
- $provinceForm = $this->getLastProvinceElement();
-
- $provinceForm->fillField('Code', $code);
- }
-
public function getFormValidationErrors(): array
{
- $errors = $this->getElement('form')->findAll('css', '.sylius-validation-error:not(.pointing)');
+ $errors = $this->getElement('form')->findAll('css', '.alert-danger');
return array_map(fn (NodeElement $element) => $element->getText(), $errors);
}
public function getValidationMessage(string $element): string
{
- $provinceForm = $this->getLastProvinceElement();
+ $province = $this->getElement('last_province');
- $foundElement = $provinceForm->find('css', '.sylius-validation-error');
+ $foundElement = $province->find('css', '.invalid-feedback');
if (null === $foundElement) {
- throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.invalid-feedback');
}
return $foundElement->getText();
@@ -132,20 +116,25 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_country_code',
- 'enabled' => '#sylius_country_enabled',
+ 'code' => '[data-test-code]',
+ 'enabled' => '[data-test-enabled]',
+ 'provinces' => '[data-test-provinces]',
+ 'last_province' => '[data-test-provinces] [data-test-province]:last-child',
+ 'add_province' => '[data-test-add-province]',
'form' => 'form',
- 'provinces' => '#sylius_country_provinces',
]);
}
- private function getLastProvinceElement(): NodeElement
+ private function getProvinceItems(): array
{
- $provinces = $this->getElement('provinces');
- $items = $provinces->findAll('css', 'div[data-form-collection="item"]');
+ $items = $this->getElement('provinces')->findAll('css', '[data-test-province]');
+ Assert::isArray($items);
- Assert::notEmpty($items);
+ return $items;
+ }
- return end($items);
+ private function getProvinceElement(string $provinceName): NodeElement|null
+ {
+ return $this->getDocument()->find('xpath', sprintf('//*[@data-test-province and .//*[contains(@value, \'%s\')]]', $provinceName));
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php
index 37fa7677af..69592dc510 100644
--- a/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php
@@ -23,22 +23,20 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function isCodeFieldDisabled(): bool;
+ public function addProvince(): void;
+
+ public function specifyProvinceName(string $name): void;
+
+ public function specifyProvinceCode(string $code): void;
+
+ public function specifyProvinceAbbreviation(string $abbreviation): void;
+
public function isThereProvince(string $provinceName): bool;
public function isThereProvinceWithCode(string $provinceCode): bool;
- public function addProvince(string $name, string $code, ?string $abbreviation = null): void;
-
public function removeProvince(string $provinceName): void;
- public function clickAddProvinceButton(): void;
-
- public function nameProvince(string $provinceName): void;
-
- public function removeProvinceName(string $provinceName): void;
-
- public function specifyProvinceCode(string $provinceCode): void;
-
/** @return array */
public function getFormValidationErrors(): array;
}
diff --git a/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php b/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php
index e5df0c285e..f4a9777280 100644
--- a/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php
@@ -19,6 +19,7 @@ use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException;
+use Sylius\Behat\Service\DriverHelper;
use Symfony\Component\Routing\RouterInterface;
class CreatePage extends SymfonyPage implements CreatePageInterface
@@ -34,6 +35,9 @@ class CreatePage extends SymfonyPage implements CreatePageInterface
public function create(): void
{
+ if (DriverHelper::isJavascript($this->getDriver())) {
+ $this->getDocument()->find('css', 'body')->click();
+ }
$this->getDocument()->pressButton('Create');
}
@@ -44,9 +48,9 @@ class CreatePage extends SymfonyPage implements CreatePageInterface
throw new ElementNotFoundException($this->getSession(), 'Field element');
}
- $validationMessage = $foundElement->find('css', '.sylius-validation-error');
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
return $validationMessage->getText();
diff --git a/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php b/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php
index d85544cdee..ddd03bd7e1 100644
--- a/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php
@@ -98,7 +98,7 @@ class IndexPage extends SymfonyPage implements IndexPageInterface
$deletedRow = $tableAccessor->getRowWithFields($table, $parameters);
$actionButtons = $tableAccessor->getFieldFromRow($table, $deletedRow, 'actions');
- $actionButtons->pressButton('Delete');
+ $actionButtons->pressButton('delete');
}
public function getActionsForResource(array $parameters): NodeElement
@@ -117,7 +117,7 @@ class IndexPage extends SymfonyPage implements IndexPageInterface
$table = $this->getElement('table');
$resourceRow = $tableAccessor->getRowWithFields($table, $parameters);
- $bulkCheckbox = $resourceRow->find('css', '.bulk-select-checkbox');
+ $bulkCheckbox = $resourceRow->find('css', '.form-check-input');
Assert::notNull($bulkCheckbox);
@@ -160,13 +160,30 @@ class IndexPage extends SymfonyPage implements IndexPageInterface
return $this->tableAccessor;
}
+ protected function toggleFilters(): void
+ {
+ $filtersToggle = $this->getElement('filters_toggle');
+ $filtersToggle->click();
+ $this->getDocument()->waitFor(1, function () use ($filtersToggle) {
+ $accordionCollapse = $filtersToggle->find('css', '.accordion-collapse');
+
+ return null !== $accordionCollapse && !$accordionCollapse->hasClass('collapsing');
+ });
+ }
+
+ protected function areFiltersVisible(): bool
+ {
+ return !$this->getElement('filters_toggle')->hasClass('collapsed');
+ }
+
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
'bulk_actions' => '.sylius-grid-nav__bulk',
- 'confirmation_button' => '#confirmation-button',
+ 'confirmation_button' => '[data-confirm-btn-true]',
'enabled_filter' => '#criteria_enabled',
- 'filter' => 'button:contains("Filter")',
+ 'filter' => '[data-test-filter]',
+ 'filters_toggle' => '.accordion-button',
'table' => '.table',
]);
}
diff --git a/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php
index af2989c39a..127d5ce6d7 100644
--- a/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php
@@ -19,6 +19,7 @@ use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException;
+use Sylius\Behat\Service\DriverHelper;
use Sylius\Component\Core\Formatter\StringInflector;
use Symfony\Component\Routing\RouterInterface;
@@ -28,14 +29,17 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface
Session $session,
$minkParameters,
RouterInterface $router,
- private string $routeName,
+ private readonly string $routeName,
) {
parent::__construct($session, $minkParameters, $router);
}
public function saveChanges(): void
{
- $this->getDocument()->pressButton('sylius_save_changes_button');
+ if (DriverHelper::isJavascript($this->getDriver())) {
+ $this->getDocument()->find('css', 'body')->click();
+ }
+ $this->getDocument()->find('css', '[data-test-update-changes-button]')->click();
}
public function cancelChanges(): void
@@ -50,14 +54,17 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface
throw new ElementNotFoundException($this->getSession(), 'Field element');
}
- $validationMessage = $foundElement->find('css', '.sylius-validation-error');
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
return $validationMessage->getText();
}
+ /**
+ * @param array $parameters
+ */
public function hasResourceValues(array $parameters): bool
{
foreach ($parameters as $element => $value) {
@@ -100,7 +107,7 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface
/**
* @throws ElementNotFoundException
*/
- private function getFieldElement(string $element): ?NodeElement
+ private function getFieldElement(string $element): NodeElement
{
$element = $this->getElement(StringInflector::nameToCode($element));
while (null !== $element && !$element->hasClass('field')) {
diff --git a/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php b/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php
index 1e6b4c791e..6093a2fa61 100644
--- a/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php
@@ -13,12 +13,26 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Customer;
+use Behat\Mink\Session;
use Sylius\Behat\Page\Admin\Crud\IndexPage as BaseIndexPage;
-use Sylius\Behat\Service\AutocompleteHelper;
+use Sylius\Behat\Service\Accessor\TableAccessorInterface;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Component\Customer\Model\CustomerInterface;
+use Symfony\Component\Routing\RouterInterface;
class IndexPage extends BaseIndexPage implements IndexPageInterface
{
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ TableAccessorInterface $tableAccessor,
+ string $routeName,
+ private AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $tableAccessor, $routeName);
+ }
+
public function getCustomerAccountStatus(CustomerInterface $customer): string
{
$tableAccessor = $this->getTableAccessor();
@@ -39,17 +53,37 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface
return $tableAccessor->getFieldFromRow($table, $row, 'verified')->getText() === 'Yes';
}
- public function specifyFilterGroup(string $groupName): void
+ public function setFilterGroup(string $groupName): void
{
- $groupFilterElement = $this->getElement('filter_group')->getParent();
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $this->getElement('filter_group')->getXpath(),
+ $groupName,
+ );
- AutocompleteHelper::chooseValue($this->getSession(), $groupFilterElement, $groupName);
+ $this->waitForFormUpdate();
+ }
+
+ public function setFilterSearch(string $phrase): void
+ {
+ $this->getElement('filter_search')->setValue($phrase);
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
'filter_group' => '#criteria_group',
+ 'filter_search' => '#criteria_search_value',
+ 'filters_form' => '[data-test-filters-form]',
]);
}
+
+ private function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('filters_form');
+ sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
}
diff --git a/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php b/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php
index a1ef8dd3e7..20f91c4b49 100644
--- a/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php
@@ -22,5 +22,7 @@ interface IndexPageInterface extends BaseIndexPageInterface
public function isCustomerVerified(CustomerInterface $customer): bool;
- public function specifyFilterGroup(string $groupName): void;
+ public function setFilterGroup(string $groupName): void;
+
+ public function setFilterSearch(string $phrase): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php b/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php
index 1b1e5cbefb..0b8254214d 100644
--- a/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php
+++ b/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php
@@ -13,23 +13,13 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Customer;
-use Behat\Mink\Element\NodeElement;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
-use Webmozart\Assert\Assert;
class ShowPage extends SymfonyPage implements ShowPageInterface
{
- public function isRegistered(): bool
- {
- $username = $this->getDocument()->find('css', '#username');
-
- return null !== $username;
- }
-
public function deleteAccount(): void
{
- $deleteButton = $this->getElement('delete_account_button');
- $deleteButton->pressButton('Delete');
+ $this->getElement('delete_account_button')->press();
}
public function getCustomerEmail(): string
@@ -49,7 +39,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function getRegistrationDate(): \DateTimeInterface
{
- return new \DateTime(str_replace('Customer since ', '', $this->getElement('registration_date')->getText()));
+ return \DateTime::createFromFormat('d-m-Y H:i:s', $this->getElement('registration_date')->getText());
}
public function getDefaultAddress(): string
@@ -59,17 +49,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasAccount(): bool
{
- return $this->hasElement('no_account');
+ return $this->hasElement('delete_account_button');
}
public function isSubscribedToNewsletter(): bool
{
- $subscribedToNewsletter = $this->getElement('subscribed_to_newsletter');
- if ($subscribedToNewsletter->find('css', 'i.green')) {
- return true;
- }
-
- return false;
+ return null !== $this->getElement('subscribed_to_newsletter')->find('css', 'svg.text-green');
}
public function hasDefaultAddressProvinceName(string $provinceName): bool
@@ -81,23 +66,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasVerifiedEmail(): bool
{
- $verifiedEmail = $this->getElement('verified_email');
- if ($verifiedEmail->find('css', 'i.green')) {
- return true;
- }
-
- return false;
+ return null !== $this->getElement('verified_email')->find('css', 'svg.text-green');
}
public function getGroupName(): string
{
- $group = $this->getElement('group');
-
- Assert::notNull($group, 'There should be element group on page.');
-
- [$text, $groupName] = explode(':', $group->getText());
-
- return trim($groupName);
+ return $this->getElement('group')->getText();
}
public function hasEmailVerificationInformation(): bool
@@ -117,34 +91,22 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasCustomerPlacedAnyOrders(): bool
{
- return null !== $this->getElement('statistics')->find('css', '.sylius-orders-overall-count');
+ return !$this->hasElement('statistics_no_orders');
}
- public function getOrdersCountInChannel(string $channelName): int
+ public function getOrdersCountInChannel(string $channelCode): int
{
- return (int) $this
- ->getStatisticsForChannel($channelName)
- ->find('css', '.sylius-orders-count')
- ->getText()
- ;
+ return (int) $this->getElement('statistics_orders_count', ['%channelCode%' => $channelCode])->getText();
}
- public function getOrdersTotalInChannel(string $channelName): string
+ public function getOrdersTotalInChannel(string $channelCode): string
{
- return $this
- ->getStatisticsForChannel($channelName)
- ->find('css', '.sylius-orders-total')
- ->getText()
- ;
+ return $this->getElement('statistics_orders_total', ['%channelCode%' => $channelCode])->getText();
}
- public function getAverageTotalInChannel(string $channelName): string
+ public function getAverageTotalInChannel(string $channelCode): string
{
- return $this
- ->getStatisticsForChannel($channelName)
- ->find('css', '.sylius-order-average-total')
- ->getText()
- ;
+ return $this->getElement('statistics_orders_average', ['%channelCode%' => $channelCode])->getText();
}
public function getSuccessFlashMessage(): string
@@ -160,48 +122,20 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'customer_email' => '#info .content.extra > a',
- 'customer_name' => '#info .content > a',
- 'customer_phone_number' => '#phone-number',
- 'default_address' => '#default-address',
- 'delete_account_button' => '#actions',
- 'flash_message' => '.ui.icon.positive.message .content p',
- 'group' => '.group',
- 'impersonate_button' => '#impersonate',
- 'no_account' => '#no-account',
- 'statistics' => '#statistics',
- 'registration_date' => '#info .content .date',
- 'subscribed_to_newsletter' => '#subscribed-to-newsletter',
- 'verified_email' => '#verified-email',
+ 'customer_email' => '[data-test-customer-email]',
+ 'customer_name' => '[data-test-customer-fullname]',
+ 'customer_phone_number' => '[data-test-customer-phone]',
+ 'default_address' => '[data-test-customer-default-address]',
+ 'delete_account_button' => '[data-test-customer-actions-delete]',
+ 'group' => '[data-test-customer-group]',
+ 'impersonate_button' => '[data-test-customer-actions-impersonate]',
+ 'registration_date' => '[data-test-customer-since]',
+ 'statistics_no_orders' => '[data-test-customer-statistics-no-orders]',
+ 'statistics_orders_average' => '[data-test-customer-statistics-%channelCode%-orders-average]',
+ 'statistics_orders_count' => '[data-test-customer-statistics-%channelCode%-orders-count]',
+ 'statistics_orders_total' => '[data-test-customer-statistics-%channelCode%-orders-total]',
+ 'subscribed_to_newsletter' => '[data-test-customer-subscribed-to-newsletter]',
+ 'verified_email' => '[data-test-customer-verified-email]',
]);
}
-
- /**
- * @throws \InvalidArgumentException
- */
- private function getStatisticsForChannel(string $channelName): NodeElement
- {
- $statisticsRibs = $this
- ->getElement('statistics')
- ->findAll('css', '.row > .column > .statistic > .sylius-channel-name')
- ;
-
- $statisticsRibs = array_filter($statisticsRibs, fn (NodeElement $statistic) => $channelName === trim($statistic->getText()));
-
- $actualStatisticsCount = count($statisticsRibs);
- Assert::same(
- 1,
- $actualStatisticsCount,
- sprintf(
- 'Expected a single statistic for channel "%s", but %d were found.',
- $channelName,
- $actualStatisticsCount,
- ),
- );
-
- $statisticsContents = $this->getElement('statistics')->findAll('css', '.row');
- $contentIndexes = array_keys($statisticsRibs);
-
- return $statisticsContents[reset($contentIndexes)];
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php b/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php
index 8b93e8010f..668d457431 100644
--- a/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php
@@ -13,16 +13,10 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Customer;
-use Behat\Mink\Exception\ElementNotFoundException;
use FriendsOfBehat\PageObjectExtension\Page\PageInterface;
interface ShowPageInterface extends PageInterface
{
- public function isRegistered(): bool;
-
- /**
- * @throws ElementNotFoundException If there is no delete account button on the page
- */
public function deleteAccount(): void;
public function getCustomerEmail(): string;
@@ -53,11 +47,11 @@ interface ShowPageInterface extends PageInterface
public function hasCustomerPlacedAnyOrders(): bool;
- public function getOrdersCountInChannel(string $channelName): int;
+ public function getOrdersCountInChannel(string $channelCode): int;
- public function getOrdersTotalInChannel(string $channelName): string;
+ public function getOrdersTotalInChannel(string $channelCode): string;
- public function getAverageTotalInChannel(string $channelName): string;
+ public function getAverageTotalInChannel(string $channelCode): string;
public function getSuccessFlashMessage(): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/DashboardPage.php b/src/Sylius/Behat/Page/Admin/DashboardPage.php
index c639bf66be..fed132d0bf 100644
--- a/src/Sylius/Behat/Page/Admin/DashboardPage.php
+++ b/src/Sylius/Behat/Page/Admin/DashboardPage.php
@@ -138,7 +138,7 @@ class DashboardPage extends SymfonyPage implements DashboardPageInterface
'channel_choosing_link' => 'a:contains("%channelName%")',
'customer_list' => '#customers',
'dropdown' => 'i.dropdown',
- 'logout' => '#sylius-logout-button',
+ 'logout' => '[data-test-user-dropdown-item="Logout"]',
'month_split_by_days_statistics_button' => 'button[data-stats-button="month"]',
'navigation_next' => '#navigation-next',
'navigation_previous' => '#navigation-prev',
diff --git a/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php b/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php
index a694a6cf3f..9f0946d18b 100644
--- a/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php
+++ b/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php
@@ -22,13 +22,21 @@ class HistoryPage extends SymfonyPage implements HistoryPageInterface
return 'sylius_admin_order_history';
}
- public function countShippingAddressChanges(): int
- {
- return count($this->getDocument()->findAll('css', '#shipping-address-changes tbody tr'));
- }
-
public function countBillingAddressChanges(): int
{
- return count($this->getDocument()->findAll('css', '#billing-address-changes tbody tr'));
+ return count($this->getElement('billing_address_logs')->findAll('css', '[data-test-address-log]'));
+ }
+
+ public function countShippingAddressChanges(): int
+ {
+ return count($this->getElement('shipping_address_logs')->findAll('css', '[data-test-address-log]'));
+ }
+
+ protected function getDefinedElements(): array
+ {
+ return array_merge(parent::getDefinedElements(), [
+ 'billing_address_logs' => '[data-test-address-type="Billing address"]',
+ 'shipping_address_logs' => '[data-test-address-type="Shipping address"]',
+ ]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php b/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php
index 10d174abab..38daaa0121 100644
--- a/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php
@@ -17,7 +17,7 @@ use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
interface HistoryPageInterface extends SymfonyPageInterface
{
- public function countShippingAddressChanges(): int;
-
public function countBillingAddressChanges(): int;
+
+ public function countShippingAddressChanges(): int;
}
diff --git a/src/Sylius/Behat/Page/Admin/Order/ShowPage.php b/src/Sylius/Behat/Page/Admin/Order/ShowPage.php
index 991da2ff16..efa4e7f274 100644
--- a/src/Sylius/Behat/Page/Admin/Order/ShowPage.php
+++ b/src/Sylius/Behat/Page/Admin/Order/ShowPage.php
@@ -18,7 +18,6 @@ use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use Sylius\Behat\Service\Accessor\TableAccessorInterface;
-use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\Routing\RouterInterface;
@@ -29,7 +28,6 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
$minkParameters,
RouterInterface $router,
private TableAccessorInterface $tableAccessor,
- private MoneyFormatterInterface $moneyFormatter,
) {
parent::__construct($session, $minkParameters, $router);
}
@@ -66,48 +64,65 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
return $this->hasAddress($billingAddressText, $customerName, $street, $postcode, $city, $countryName);
}
- public function hasShipment(string $shippingDetails): bool
+ public function hasShipment(string $shippingMethodName): bool
{
$shipmentsText = $this->getElement('shipments')->getText();
- return stripos($shipmentsText, $shippingDetails) !== false;
+ return stripos($shipmentsText, $shippingMethodName) !== false;
+ }
+
+ public function hasShipmentWithState(string $state): bool
+ {
+ foreach ($this->getElement('shipments')->findAll('css', '[data-test-shipment-state]') as $shipmentState) {
+ if (0 === strcasecmp($state, $shipmentState->getText())) {
+ return true;
+ }
+ }
+
+ return false;
}
public function specifyTrackingCode(string $code): void
{
- $this->getDocument()->fillField('sylius_shipment_ship_tracking', $code);
+ $this->getElement('shipment_tracking')->setValue($code);
}
public function canShipOrder(OrderInterface $order): bool
{
- return $this->getLastOrderShipmentElement($order)->hasButton('Ship');
+ return $this->hasElement('shipment_ship_button');
}
public function shipOrder(OrderInterface $order): void
{
- $this->getLastOrderShipmentElement($order)->pressButton('Ship');
+ $this->getElement('shipment_ship_button')->press();
}
- public function hasPayment(string $paymentDetails): bool
+ public function hasPayment(string $paymentMethodName): bool
{
$paymentsText = $this->getElement('payments')->getText();
- return stripos($paymentsText, $paymentDetails) !== false;
+ return stripos($paymentsText, $paymentMethodName) !== false;
}
public function canCompleteOrderLastPayment(OrderInterface $order): bool
{
- return $this->getLastOrderPaymentElement($order)->hasButton('Complete');
+ $lastPayment = $order->getLastPayment();
+
+ return $this->hasElement('payment_complete', ['%paymentId%' => $lastPayment->getId()]);
}
public function completeOrderLastPayment(OrderInterface $order): void
{
- $this->getLastOrderPaymentElement($order)->pressButton('Complete');
+ $lastPayment = $order->getLastPayment();
+
+ $this->getElement('payment_complete', ['%paymentId%' => $lastPayment->getId()])->submit();
}
public function refundOrderLastPayment(OrderInterface $order): void
{
- $this->getLastOrderPaymentElement($order)->pressButton('Refund');
+ $lastPayment = $order->getLastPayment();
+
+ $this->getElement('payment_refund', ['%paymentId%' => $lastPayment->getId()])->submit();
}
public function countItems(): int
@@ -269,18 +284,14 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function getPaymentAmount(): string
{
- $paymentsPrice = $this->getElement('payments')->find('css', '.description');
+ $paymentsPrice = $this->getElement('payments')->find('css', '[data-test-payment-amount]');
return $paymentsPrice->getText();
}
public function getPaymentsCount(): int
{
- try {
- $payments = $this->getElement('payments')->findAll('css', '.item');
- } catch (ElementNotFoundException) {
- return 0;
- }
+ $payments = $this->getElement('payments')->findAll('css', '[data-test-payment]');
return count($payments);
}
@@ -298,7 +309,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function hasCancelButton(): bool
{
- return $this->getDocument()->hasButton('Cancel');
+ return $this->hasElement('cancel_order');
+ }
+
+ public function cancelOrder(): void
+ {
+ $this->getElement('cancel_order')->click();
}
public function getOrderState(): string
@@ -316,11 +332,6 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
return $this->getElement('order_shipping_state')->getText();
}
- public function cancelOrder(): void
- {
- $this->getDocument()->pressButton('Cancel');
- }
-
public function deleteOrder(): void
{
$this->getDocument()->pressButton('Delete');
@@ -405,32 +416,37 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'billing_address' => '#billing-address',
+ 'billing_address' => '[data-test-billing-address]',
+ 'cancel_order' => '[data-test-cancel-order]',
'currency' => '#sylius-order-currency',
'customer' => '#customer',
'ip_address' => '#ipAddress',
'items_total' => '#items-total',
'order_notes' => '#sylius-order-notes',
- 'order_payment_state' => '#payment-state > span',
+ 'order_payment_state' => '[data-test-order-payment-state]',
'order_shipping_state' => '#shipping-state > span',
- 'order_state' => '#sylius-order-state',
- 'payments' => '#sylius-payments',
+ 'order_state' => '[data-test-order-state]',
+ 'payments' => '[data-test-payments]',
+ 'payment_complete' => '[data-test-complete-payment="%paymentId%"]',
+ 'payment_refund' => '[data-test-refund-payment="%paymentId%"]',
'promotion_discounts' => '#promotion-discounts',
'promotion_shipping_discounts' => '#shipping-discount-value',
- 'promotion_total' => '#promotion-total',
+ 'promotion_total' => '[data-test-promotion-total]',
'resend_order_confirmation_email' => '[data-test-resend-order-confirmation-email]',
'resend_shipment_confirmation_email' => '[data-test-resend-shipment-confirmation-email]',
'shipment_shipped_at_date' => '#sylius-shipments .shipped-at-date',
- 'shipments' => '#sylius-shipments',
- 'shipping_address' => '#shipping-address',
+ 'shipments' => '[data-test-shipments]',
+ 'shipment_tracking' => '[data-test-shipment-tracking]',
+ 'shipment_ship_button' => '[data-test-shipment-ship-button]',
+ 'shipping_address' => '[data-test-shipping-address]',
'shipping_adjustment_name' => '#shipping-adjustment-label',
'shipping_charges' => '#shipping-base-value',
'shipping_tax' => '#shipping-tax-value',
'shipping_total' => '#shipping-total',
'table' => '.table',
- 'tax_total' => '#tax-total',
+ 'tax_total' => '[data-test-tax-total]',
'taxes' => '#taxes',
- 'total' => '#total',
+ 'total' => '[data-test-total]',
]);
}
@@ -463,29 +479,4 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
{
return $this->tableAccessor->getRowWithFields($this->getElement('table'), ['item' => $itemName]);
}
-
- protected function getLastOrderPaymentElement(OrderInterface $order): ?NodeElement
- {
- $payment = $order->getPayments()->last();
-
- $paymentStateElements = $this->getElement('payments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($payment->getState())));
- $paymentStateElement = end($paymentStateElements);
-
- return $paymentStateElement->getParent()->getParent();
- }
-
- protected function getLastOrderShipmentElement(OrderInterface $order): ?NodeElement
- {
- $shipment = $order->getShipments()->last();
-
- $shipmentStateElements = $this->getElement('shipments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($shipment->getState())));
- $shipmentStateElement = end($shipmentStateElements);
-
- return $shipmentStateElement->getParent()->getParent();
- }
-
- protected function getFormattedMoney(int $orderPromotionTotal): string
- {
- return $this->moneyFormatter->format($orderPromotionTotal, $this->getDocument()->find('css', '#sylius-order-currency')->getText());
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php b/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php
index 9fbd74a36a..012aca9f59 100644
--- a/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php
@@ -28,6 +28,8 @@ interface ShowPageInterface extends SymfonyPageInterface
public function hasShipment(string $shippingMethodName): bool;
+ public function hasShipmentWithState(string $state);
+
public function specifyTrackingCode(string $code): void;
public function canShipOrder(OrderInterface $order): bool;
diff --git a/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php
index 356269d3ee..98e6471e92 100644
--- a/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php
@@ -52,17 +52,47 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
{
$foundElement = $this->getFieldElement($element);
if (null === $foundElement) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
- $validationMessage = $foundElement->find('css', '.sylius-validation-error');
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
return $message === $validationMessage->getText();
}
+ public function changeBillingCountry(string $countryCode): void
+ {
+ $this->getElement('billing_country')->selectOption($countryCode);
+ $this->waitForFormUpdate();
+ }
+
+ public function changeShippingCountry(string $countryCode): void
+ {
+ $this->getElement('shipping_country')->selectOption($countryCode);
+ $this->waitForFormUpdate();
+ }
+
+ public function getAvailableProvincesForBillingAddress(): array
+ {
+ return $this->getOptionTextsFor($this->getElement('billing_province_code'));
+ }
+
+ public function getAvailableProvincesForShippingAddress(): array
+ {
+ return $this->getOptionTextsFor($this->getElement('shipping_province_code'));
+ }
+
+ /**
+ * @return array
+ */
+ private function getOptionTextsFor(NodeElement $element): array
+ {
+ return array_map(fn ($option) => $option->getText(), $element->findAll('css', 'option'));
+ }
+
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
@@ -71,12 +101,17 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
'billing_first_name' => '#sylius_order_billingAddress_firstName',
'billing_last_name' => '#sylius_order_billingAddress_lastName',
'billing_postcode' => '#sylius_order_billingAddress_postcode',
+ 'billing_province_name' => '#sylius_order_billingAddress_provinceName',
+ 'billing_province_code' => '#sylius_order_billingAddress_provinceCode',
'billing_street' => '#sylius_order_billingAddress_street',
+ 'live_form' => '[data-live-name-value="sylius_admin:order:form"]',
'shipping_city' => '#sylius_order_shippingAddress_city',
'shipping_country' => '#sylius_order_shippingAddress_countryCode',
'shipping_first_name' => '#sylius_order_shippingAddress_firstName',
'shipping_last_name' => '#sylius_order_shippingAddress_lastName',
'shipping_postcode' => '#sylius_order_shippingAddress_postcode',
+ 'shipping_province_name' => '#sylius_order_shippingAddress_provinceName',
+ 'shipping_province_code' => '#sylius_order_shippingAddress_provinceCode',
'shipping_street' => '#sylius_order_shippingAddress_street',
]);
}
@@ -109,4 +144,9 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $element;
}
+
+ private function waitForFormUpdate(): void
+ {
+ $this->getElement('live_form')->waitFor('5', fn (NodeElement $element) => !$element->hasAttribute('busy'));
+ }
}
diff --git a/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php
index 43c4720dc0..047d58c231 100644
--- a/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php
@@ -23,4 +23,18 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function specifyBillingAddress(AddressInterface $address): void;
public function checkValidationMessageFor(string $element, string $message): bool;
+
+ public function changeBillingCountry(string $countryCode): void;
+
+ public function changeShippingCountry(string $countryCode): void;
+
+ /**
+ * @return array
+ */
+ public function getAvailableProvincesForBillingAddress(): array;
+
+ /**
+ * @return array
+ */
+ public function getAvailableProvincesForShippingAddress(): array;
}
diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php
index e14563a21a..7c1ed6e234 100644
--- a/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php
@@ -99,6 +99,9 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
return $this->getElement('enabled');
}
+ /**
+ * @return array
+ */
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php
index 3f0bcf5c32..6996269a53 100644
--- a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php
@@ -38,16 +38,36 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
$this->getDocument()->fillField('Signature', $signature);
}
+ public function setStripeSecretKey(string $secretKey): void
+ {
+ $this->getDocument()->fillField('Secret key', $secretKey);
+ }
+
+ public function setStripePublishableKey(string $publishableKey): void
+ {
+ $this->getDocument()->fillField('Publishable key', $publishableKey);
+ }
+
public function nameIt(string $name, string $languageCode): void
{
$this->getDocument()->fillField(sprintf('sylius_payment_method_translations_%s_name', $languageCode), $name);
}
+ public function enableSandboxMode(): void
+ {
+ $this->getElement('sandbox')->check();
+ }
+
public function isPaymentMethodEnabled(): bool
{
return (bool) $this->getToggleableElement()->getValue();
}
+ public function isPaymentMethodInSandboxMode(): bool
+ {
+ return $this->getElement('sandbox')->hasAttribute('checked');
+ }
+
public function isFactoryNameFieldDisabled(): bool
{
return 'disabled' === $this->getElement('factory_name')->getAttribute('disabled');
@@ -55,7 +75,10 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
public function isAvailableInChannel(string $channelName): bool
{
- return $this->getElement('channel', ['%channel%' => $channelName])->hasAttribute('checked');
+ return $this
+ ->getElement('channel', ['%channel_name%' => $channelName])
+ ->hasAttribute('checked')
+ ;
}
public function getPaymentMethodInstructions(string $language): string
@@ -73,15 +96,24 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $this->getElement('enabled');
}
+ /**
+ * @return array
+ */
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'channel' => '.checkbox:contains("%channel%") input',
- 'code' => '#sylius_payment_method_code',
- 'enabled' => '#sylius_payment_method_enabled',
- 'factory_name' => '#sylius_payment_method_gatewayConfig_factoryName',
+ 'channel' => '[data-test-channel-name="%channel_name%"]',
+ 'code' => '[data-test-code]',
+ 'enabled' => '[data-test-enabled]',
+ 'factory_name' => '[data-test-factory-name]',
'instructions' => '#sylius_payment_method_translations_%language%_instructions',
'name' => '#sylius_payment_method_translations_en_US_name',
+ 'password' => '[data-test-password]',
+ 'publishable_key' => '[data-test-publishable-key]',
+ 'sandbox' => '[data-test-sandbox]',
+ 'secret_key' => '[data-test-secret-key]',
+ 'signature' => '[data-test-signature]',
+ 'username' => '[data-test-username]',
]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php
index 4aeb384583..40696b9c0d 100644
--- a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php
@@ -29,12 +29,20 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function setPaypalGatewaySignature(string $signature): void;
+ public function enableSandboxMode(): void;
+
+ public function setStripeSecretKey(string $secretKey): void;
+
+ public function setStripePublishableKey(string $publishableKey): void;
+
public function isCodeDisabled(): bool;
public function isFactoryNameFieldDisabled(): bool;
public function isPaymentMethodEnabled(): bool;
+ public function isPaymentMethodInSandboxMode(): bool;
+
public function isAvailableInChannel(string $channelName): bool;
public function getPaymentMethodInstructions(string $language): string;
diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php
index 080b49c528..de4fb44686 100644
--- a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php
@@ -14,31 +14,36 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Product;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
use Sylius\Behat\Service\AutocompleteHelper;
use Sylius\Behat\Service\DriverHelper;
-use Sylius\Behat\Service\SlugGenerationHelper;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Component\Core\Model\TaxonInterface;
+use Symfony\Component\Routing\RouterInterface;
use Webmozart\Assert\Assert;
class CreateConfigurableProductPage extends BaseCreatePage implements CreateConfigurableProductPageInterface
{
use SpecifiesItsField;
+ use FormTrait;
- public function nameItIn(string $name, string $localeCode): void
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private readonly AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
+ }
+
+ public function create(): void
{
- $this->clickTabIfItsNotActive('details');
- $this->activateLanguageTab($localeCode);
+ $this->waitForFormUpdate();
- $this->getDocument()->fillField(
- sprintf('sylius_product_translations_%s_name', $localeCode),
- $name,
- );
-
- if (DriverHelper::isJavascript($this->getDriver())) {
- SlugGenerationHelper::waitForSlugGeneration($this->getSession(), $this->getElement('slug'));
- }
+ parent::create();
}
public function hasMainTaxonWithName(string $taxonName): bool
@@ -58,29 +63,6 @@ class CreateConfigurableProductPage extends BaseCreatePage implements CreateConf
AutocompleteHelper::chooseValue($this->getSession(), $mainTaxonElement, $taxon->getName());
}
- public function selectOption(string $optionName): void
- {
- $option = $this->getElement('options_choice')->getParent();
-
- AutocompleteHelper::chooseValue($this->getSession(), $option, $optionName);
- }
-
- public function attachImage(string $path, ?string $type = null): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $filesPath = $this->getParameter('files_path');
-
- $this->getDocument()->clickLink('Add');
-
- $imageForm = $this->getLastImageElement();
- if (null !== $type) {
- $imageForm->fillField('Type', $type);
- }
-
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
public function activateLanguageTab(string $localeCode): void
{
if (DriverHelper::isNotJavascript($this->getDriver())) {
@@ -104,20 +86,24 @@ class CreateConfigurableProductPage extends BaseCreatePage implements CreateConf
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'attribute' => '.attribute',
- 'code' => '#sylius_product_code',
- 'images' => '#sylius_product_images',
- 'language_tab' => '[data-locale="%localeCode%"] .title',
- 'main_taxon' => '#sylius_product_mainTaxon',
- 'name' => '#sylius_product_translations_en_US_name',
- 'options_choice' => '#sylius_product_options',
- 'search' => '.ui.fluid.search.selection.dropdown',
- 'search_item_selected' => 'div.menu > div.item.selected',
- 'slug' => '#sylius_product_translations_en_US_slug',
- 'tab' => '.menu [data-tab="%name%"]',
- 'taxonomy' => 'a[data-tab="taxonomy"]',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ [
+ 'attribute' => '.attribute',
+ 'code' => '#sylius_product_code',
+ 'images' => '#sylius_product_images',
+ 'language_tab' => '[data-locale="%localeCode%"] .title',
+ 'main_taxon' => '#sylius_product_mainTaxon',
+ 'name' => '#sylius_product_translations_en_US_name',
+ 'options_choice' => '#sylius_product_options',
+ 'search' => '.ui.fluid.search.selection.dropdown',
+ 'search_item_selected' => 'div.menu > div.item.selected',
+ 'slug' => '#sylius_product_translations_en_US_slug',
+ 'tab' => '.menu [data-tab="%name%"]',
+ 'taxonomy' => 'a[data-tab="taxonomy"]',
+ ],
+ $this->getDefinedFormElements(),
+ );
}
private function openTaxonBookmarks(): void
diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php
index ea132c78d9..66a75b0ab6 100644
--- a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php
@@ -28,6 +28,8 @@ interface CreateConfigurableProductPageInterface extends BaseCreatePageInterface
public function selectMainTaxon(TaxonInterface $taxon): void;
+ public function hasImageWithType(string $type): bool;
+
public function attachImage(string $path, ?string $type = null): void;
public function activateLanguageTab(string $localeCode): void;
diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php
index 3cd8e39a47..4d521c2161 100644
--- a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php
@@ -14,37 +14,41 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Product;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
use Sylius\Behat\Service\AutocompleteHelper;
use Sylius\Behat\Service\DriverHelper;
-use Sylius\Behat\Service\SlugGenerationHelper;
-use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Component\Core\Model\TaxonInterface;
-use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
+use Symfony\Component\Routing\RouterInterface;
use Webmozart\Assert\Assert;
class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProductPageInterface
{
+ use FormTrait;
use SpecifiesItsField;
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private readonly AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
+ }
+
public function getRouteName(): string
{
return parent::getRouteName() . '_simple';
}
- public function nameItIn(string $name, string $localeCode): void
+ public function create(): void
{
- $this->clickTabIfItsNotActive('details');
- $this->activateLanguageTab($localeCode);
- $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
+ $this->waitForFormUpdate();
- if (DriverHelper::isJavascript($this->getDriver())) {
- SlugGenerationHelper::waitForSlugGeneration(
- $this->getSession(),
- $this->getElement('slug', ['%locale%' => $localeCode]),
- );
- }
+ parent::create();
}
public function specifySlugIn(?string $slug, string $locale): void
@@ -54,38 +58,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
$this->getElement('slug', ['%locale%' => $locale])->setValue($slug);
}
- public function specifyPrice(ChannelInterface $channel, string $price): void
- {
- $this->getElement('price', ['%channelCode%' => $channel->getCode()])->setValue($price);
- }
-
- public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void
- {
- $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
- }
-
- public function addAttribute(string $attributeName, string $value, string $localeCode): void
- {
- $this->clickTabIfItsNotActive('attributes');
-
- $attributeOption = $this->getElement('attributes_choice')->find('css', sprintf('option:contains("%s")', $attributeName));
- $this->selectElementFromAttributesDropdown($attributeOption->getAttribute('value'));
-
- $this->getDocument()->pressButton('Add attributes');
- $this->waitForFormElement();
-
- if ('' === $value) {
- return;
- }
-
- $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->setValue($value);
- }
-
- public function selectAttributeValue(string $attributeName, string $value, string $localeCode): void
- {
- $this->getElement('attribute_value_select', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->selectOption($value);
- }
-
public function addNonTranslatableAttribute(string $attributeName, string $value): void
{
$this->clickTabIfItsNotActive('attributes');
@@ -108,13 +80,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
return $validationError->getText();
}
- public function removeAttribute(string $attributeName, string $localeCode): void
- {
- $this->clickTabIfItsNotActive('attributes');
-
- $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->press();
- }
-
public function checkAttributeErrors($attributeName, $localeCode): void
{
$this->clickTabIfItsNotActive('attributes');
@@ -152,56 +117,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
$productTaxonsElement->setValue(implode(',', $productTaxonsCodes));
}
- public function attachImage(string $path, ?string $type = null): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $filesPath = $this->getParameter('files_path');
-
- $this->getDocument()->clickLink('Add');
-
- $imageForm = $this->getLastImageElement();
- if (null !== $type) {
- $imageForm->fillField('Type', $type);
- }
-
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void
- {
- $this->clickTab('associations');
-
- $dropdown = $this->getElement('association_dropdown', [
- '%association%' => $productAssociationType->getName(),
- ]);
- $dropdown->click();
-
- foreach ($productsNames as $productName) {
- $dropdown->waitFor(5, fn () => $this->hasElement('association_dropdown_item', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]));
-
- $item = $this->getElement('association_dropdown_item', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]);
- $item->click();
- }
- }
-
- public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void
- {
- $this->clickTabIfItsNotActive('associations');
-
- $item = $this->getElement('association_dropdown_item_selected', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]);
- $item->find('css', 'i.delete')->click();
- }
-
public function choosePricingCalculator(string $name): void
{
$this->getElement('price_calculator')->selectOption($name);
@@ -224,22 +139,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
}
}
- public function selectShippingCategory(string $shippingCategoryName): void
- {
- $this->getElement('shipping_category')->selectOption($shippingCategoryName);
- }
-
- public function setShippingRequired(bool $isShippingRequired): void
- {
- if ($isShippingRequired) {
- $this->getElement('shipping_required')->check();
-
- return;
- }
-
- $this->getElement('shipping_required')->uncheck();
- }
-
public function getChannelPricingValidationMessage(): string
{
return $this->getElement('prices_validation_message')->getText();
@@ -261,37 +160,41 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
- 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
- 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
- 'attribute' => '.attribute',
- 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button',
- 'attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input',
- 'attribute_value_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select',
- 'attributes_choice' => '#sylius_product_attribute_choice',
- 'cancel_button' => '[data-test-cancel-changes-button]',
- 'channel_checkbox' => '.checkbox:contains("%channelName%") input',
- 'code' => '#sylius_product_code',
- 'form' => 'form[name="sylius_product"]',
- 'images' => '#sylius_product_images',
- 'language_tab' => '[data-locale="%locale%"] .title',
- 'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
- 'main_taxon' => '#sylius_product_mainTaxon',
- 'product_taxons' => '#sylius_product_productTaxons',
- 'name' => '#sylius_product_translations_%locale%_name',
- 'non_translatable_attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input',
- 'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice',
- 'price' => '#sylius_product_variant_channelPricings_%channelCode%_price',
- 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error',
- 'price_calculator' => '#sylius_product_variant_pricingCalculator',
- 'shipping_category' => '#sylius_product_variant_shippingCategory',
- 'shipping_required' => '#sylius_product_variant_shippingRequired',
- 'slug' => '#sylius_product_translations_%locale%_slug',
- 'tab' => '.menu [data-tab="%name%"]',
- 'taxonomy' => 'a[data-tab="taxonomy"]',
- 'toggle_slug_modification_button' => '.toggle-product-slug-modification',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ [
+ 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
+ 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
+ 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
+ 'attribute' => '.attribute',
+ 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button',
+ 'attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input',
+ 'attribute_value_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select',
+ 'attributes_choice' => '#sylius_product_attribute_choice',
+ 'cancel_button' => '[data-test-cancel-changes-button]',
+ 'channel_checkbox' => '.checkbox:contains("%channelName%") input',
+ 'code' => '#sylius_product_code',
+ 'form' => 'form[name="sylius_product"]',
+ 'images' => '#sylius_product_images',
+ 'language_tab' => '[data-locale="%locale%"] .title',
+ 'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
+ 'main_taxon' => '#sylius_product_mainTaxon',
+ 'product_taxons' => '#sylius_product_productTaxons',
+ 'name' => '#sylius_product_translations_%locale%_name',
+ 'non_translatable_attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input',
+ 'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice',
+ 'price' => '#sylius_product_variant_channelPricings_%channelCode%_price',
+ 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error',
+ 'price_calculator' => '#sylius_product_variant_pricingCalculator',
+ 'shipping_category' => '#sylius_product_variant_shippingCategory',
+ 'shipping_required' => '#sylius_product_variant_shippingRequired',
+ 'slug' => '#sylius_product_translations_%locale%_slug',
+ 'tab' => '.menu [data-tab="%name%"]',
+ 'taxonomy' => 'a[data-tab="taxonomy"]',
+ 'toggle_slug_modification_button' => '.toggle-product-slug-modification',
+ ],
+ $this->getDefinedFormElements(),
+ );
}
private function openTaxonBookmarks(): void
diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php
index dfd9e1ff8c..c6a995de94 100644
--- a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php
@@ -15,6 +15,7 @@ namespace Sylius\Behat\Page\Admin\Product;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
@@ -34,9 +35,9 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface
public function specifySlugIn(?string $slug, string $locale): void;
- public function addAttribute(string $attributeName, string $value, string $localeCode): void;
+ public function addAttribute(string $attributeName): void;
- public function selectAttributeValue(string $attributeName, string $value, string $localeCode): void;
+ public function updateAttribute(string $attributeName, string $value, string $localeCode): void;
public function addNonTranslatableAttribute(string $attributeName, string $value): void;
@@ -50,6 +51,8 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface
public function checkProductTaxon(TaxonInterface $taxon): void;
+ public function hasImageWithType(string $type): bool;
+
public function attachImage(string $path, ?string $type = null): void;
/**
@@ -57,7 +60,7 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface
*/
public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void;
- public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void;
+ public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void;
public function activateLanguageTab(string $locale): void;
diff --git a/src/Sylius/Behat/Page/Admin/Product/FormTrait.php b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php
new file mode 100644
index 0000000000..237dfa216a
--- /dev/null
+++ b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php
@@ -0,0 +1,404 @@
+ '[data-test-attribute-value][data-test-locale-code="%localeCode%"][data-test-attribute-name="%attributeName%"]',
+ 'channel_tab' => '[data-test-channel-tab="%channelCode%"]',
+ 'form' => '[data-live-name-value="sylius_admin:product:form"]',
+ 'field_associations' => '[name="sylius_product[associations][%association%][]"]',
+ 'field_name' => '[name="sylius_product[translations][%localeCode%][name]"]',
+ 'field_slug' => '[name="sylius_product[translations][%localeCode%][slug]"]',
+ 'field_price' => '[name="sylius_product[variant][channelPricings][%channelCode%][price]"]',
+ 'field_original_price' => '[name="sylius_product[variant][channelPricings][%channelCode%][originalPrice]"]',
+ 'field_shipping_category' => '[name="sylius_product[variant][shippingCategory]"]',
+ 'field_shipping_required' => '[name="sylius_product[variant][shippingRequired]"]',
+ 'generate_product_slug_button' => '[data-test-generate-product-slug-button="%localeCode%"]',
+ 'images' => '[data-test-images]',
+ 'image_subform' => '[data-test-image-subform]',
+ 'image_subform_with_type' => '[data-test-image-subform][data-test-type="%type%"]',
+ 'images_subforms' => '[data-test-image-subforms]',
+ 'product_attribute_autocomplete' => '[data-test-product-attribute-autocomplete]',
+ 'product_attribute_delete_button' => '[data-test-product-attribute-delete-button="%attributeName%"]',
+ 'product_attribute_input' => 'input[name="product_attributes"]',
+ 'product_attribute_tab' => '[data-test-product-attribute-tab="%name%"]',
+ 'product_options_autocomplete' => '[data-test-product-options-autocomplete]',
+ 'product_translation_accordion' => '[data-test-product-translations-accordion="%localeCode%"]',
+ 'side_navigation_tab' => '[data-test-side-navigation-tab="%name%"]',
+ ];
+ }
+
+ /*
+ * Filling fields
+ */
+
+ public function nameItIn(string $name, string $localeCode): void
+ {
+ $this->changeTab('translations');
+ $this->expandTranslationAccordion($localeCode);
+ $this->getElement('field_name', ['%localeCode%' => $localeCode])->setValue($name);
+
+ if (DriverHelper::isJavascript($this->getDriver())) {
+ $this->getElement('generate_product_slug_button', ['%localeCode%' => $localeCode])->click();
+ $this->waitForFormUpdate();
+ }
+ }
+
+ public function specifyPrice(ChannelInterface $channel, string $price): void
+ {
+ $this->changeTab('channel-pricing');
+ $this->changeChannelTab($channel->getCode());
+ $this->getElement('field_price', ['%channelCode%' => $channel->getCode()])->setValue($price);
+ }
+
+ // TODO: Move to the Simple Product specific class
+ public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void
+ {
+ $this->changeTab('channel-pricing');
+ $this->changeChannelTab($channel->getCode());
+ $this->getElement('field_original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
+ }
+
+ // TODO: Move to the Simple Product specific class
+ public function selectShippingCategory(string $shippingCategoryName): void
+ {
+ $this->changeTab('shipping');
+ $this->getElement('field_shipping_category')->selectOption($shippingCategoryName);
+ }
+
+ // TODO: Move to the Simple Product specific class
+ public function setShippingRequired(bool $isShippingRequired): void
+ {
+ $this->changeTab('details');
+
+ if ($isShippingRequired) {
+ $this->getElement('field_shipping_required')->check();
+
+ return;
+ }
+
+ $this->getElement('field_shipping_required')->uncheck();
+ }
+
+ // TODO: Move to the Simple Product specific class
+ public function isShippingRequired(): bool
+ {
+ return $this->getElement('field_shipping_required')->isChecked();
+ }
+
+ // TODO: Move to the Configurable Product specific class
+ public function selectOption(string $optionName): void
+ {
+ $this->changeTab('details');
+ $productOptionsAutocomplete = $this->getElement('product_options_autocomplete');
+
+ $this->autocompleteHelper->selectByName($this->getDriver(), $productOptionsAutocomplete->getXpath(), $optionName);
+ }
+
+ public function hasTab(string $name): bool
+ {
+ return $this->hasElement('side_navigation_tab', ['%name%' => $name]);
+ }
+
+ /*
+ * Tabs management
+ */
+
+ private function changeTab(string $tabName): void
+ {
+ $this->getElement('side_navigation_tab', ['%name%' => $tabName])->click();
+ }
+
+ private function changeChannelTab(string $channelCode): void
+ {
+ $this->getElement('channel_tab', ['%channelCode%' => $channelCode])->click();
+ }
+
+ private function changeAttributeTab(string $attributeName): void
+ {
+ $this->getElement('product_attribute_tab', ['%name%' => $attributeName])->click();
+ }
+
+ private function expandTranslationAccordion(string $localeCode): void
+ {
+ $translationAccordion = $this->getElement('product_translation_accordion', ['%localeCode%' => $localeCode]);
+
+ if ($translationAccordion->getAttribute('aria-expanded') === 'true') {
+ return;
+ }
+
+ $translationAccordion->click();
+ }
+
+ /*
+ * Attribute management
+ */
+
+ public function addAttribute(string $attributeName): void
+ {
+ $this->changeTab('attributes');
+ $this->selectAttributeToBeAdded($attributeName);
+ $this->clickButton('Add');
+
+ $this->waitForFormUpdate();
+ }
+
+ public function updateAttribute(string $attributeName, string $value, string $localeCode): void
+ {
+ $this->changeTab('attributes');
+ $this->changeAttributeTab($attributeName);
+
+ $attributeValue = $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode]);
+
+ match ($attributeValue->getTagName()) {
+ 'input' => $attributeValue->setValue($value),
+ 'select' => $attributeValue->selectOption($value),
+ default => throw new \InvalidArgumentException('Unsupported attribute value type'),
+ };
+
+ $attributeValue->blur();
+ $this->waitForFormUpdate();
+ }
+
+ public function removeAttribute(string $attributeName, string $localeCode): void
+ {
+ $this->changeTab('attributes');
+
+ $this->getElement('product_attribute_delete_button', ['%attributeName%' => $attributeName])->press();
+
+ $this->waitForFormUpdate();
+ }
+
+ public function getAttributeValue(string $attribute, string $localeCode): string
+ {
+ $this->changeTab('attributes');
+ $this->changeAttributeTab($attribute);
+
+ $attributeValue = $this->getElement('attribute_value', ['%attributeName%' => $attribute, '%localeCode%' => $localeCode]);
+
+ return match ($attributeValue->getTagName()) {
+ 'input' => $attributeValue->getValue(),
+ 'select' => $attributeValue->getText(),
+ default => throw new \InvalidArgumentException('Unsupported attribute value type'),
+ };
+ }
+
+ public function addSelectedAttributes(): void
+ {
+ $this->changeTab('attributes');
+ $this->clickButton('Add');
+ $this->waitForFormUpdate();
+ }
+
+ public function getNumberOfAttributes(): int
+ {
+ return count($this->getDocument()->findAll('css', '[data-test-product-attribute-tab]'));
+ }
+
+ private function selectAttributeToBeAdded(string $attributeName): void
+ {
+ $driver = $this->getDriver();
+ $this->autocompleteHelper->selectByName(
+ $driver,
+ $this->getElement('product_attribute_input')->getXpath(),
+ $attributeName,
+ );
+ }
+
+ /*
+ * Associations management
+ */
+
+ public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void
+ {
+ $this->changeTab('associations');
+ $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]);
+
+ foreach ($productsNames as $productName) {
+ $this->autocompleteHelper->selectByName(
+ $this->getDriver(),
+ $associationField->getXpath(),
+ $productName,
+ );
+ $this->waitForFormUpdate();
+ }
+ }
+
+ public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void
+ {
+ $this->changeTab('associations');
+ $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]);
+
+ $this->autocompleteHelper->removeByValue(
+ $this->getDriver(),
+ $associationField->getXpath(),
+ $product->getCode(),
+ );
+ }
+
+ public function hasAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): bool
+ {
+ $this->changeTab('associations');
+ $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]);
+
+ return in_array($product->getCode(), $associationField->getValue(), true);
+ }
+
+ /*
+ * Media management
+ */
+
+ public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void
+ {
+ $this->changeTab('media');
+ $this->clickButton('Add image');
+ $this->waitForFormUpdate();
+
+ $images = $this->getElement('images');
+ $imagesSubform = $images->findAll('css', '[data-test-image-subform]');
+ $imageSubform = end($imagesSubform);
+
+ if (null !== $type) {
+ $imageSubform->fillField('Type', $type);
+ }
+
+ if (null !== $productVariant) {
+ $this->autocompleteHelper->selectByValue(
+ $this->getDriver(),
+ $imageSubform->find('css', '[data-test-product-variant]')->getXpath(),
+ $productVariant->getCode(),
+ );
+ }
+
+ $filesPath = $this->getParameter('files_path');
+ $imageSubform->find('css', '[data-test-file]')->attachFile($filesPath . $path);
+ }
+
+ public function changeImageWithType(string $type, string $path): void
+ {
+ $filesPath = $this->getParameter('files_path');
+
+ $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]);
+ $imageSubform->find('css', '[data-test-file]')->attachFile($filesPath . $path);
+ }
+
+ public function removeImageWithType(string $type): void
+ {
+ $this->changeTab('media');
+
+ $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]);
+ $imageSubform->find('css', '[data-test-image-delete]')->click();
+ $this->waitForFormUpdate();
+ }
+
+ public function removeFirstImage(): void
+ {
+ $this->changeTab('media');
+ $firstSubform = $this->getFirstImageSubform();
+ $firstSubform->findAll('css', '[data-test-image-delete]')[0]->click();
+ }
+
+ public function hasImageWithType(string $type): bool
+ {
+ $this->changeTab('media');
+
+ try {
+ $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]);
+ } catch (ElementNotFoundException) {
+ return false;
+ }
+
+ $imageUrl = $imageSubform->getAttribute('data-test-image-url');
+ $this->getDriver()->visit($imageUrl);
+ $statusCode = $this->getDriver()->getStatusCode();
+ $this->getDriver()->back();
+
+ return in_array($statusCode, [200, 304], true);
+ }
+
+ public function hasImageWithVariant(ProductVariantInterface $productVariant): bool
+ {
+ $this->changeTab('media');
+ $images = $this->getElement('images');
+
+ return $images->has('css', sprintf('[data-test-product-variant="%s"]', $productVariant->getCode()));
+ }
+
+ public function countImages(): int
+ {
+ $images = $this->getElement('images');
+ $imageSubforms = $images->findAll('css', '[data-test-image-subform]');
+
+ return count($imageSubforms);
+ }
+
+ public function modifyFirstImageType(string $type): void
+ {
+ $this->changeTab('media');
+
+ $firstImageSubform = $this->getFirstImageSubform();
+
+ $firstImageSubform->find('css', 'input[data-test-type]')->setValue($type);
+ }
+
+ public function selectVariantForFirstImage(ProductVariantInterface $productVariant): void
+ {
+ $this->changeTab('media');
+
+ $imageSubform = $this->getFirstImageSubform();
+ $this->autocompleteHelper->selectByValue(
+ $this->getDriver(),
+ $imageSubform->find('css', '[data-test-product-variant]')->getXpath(),
+ $productVariant->getCode(),
+ );
+ }
+
+ private function getFirstImageSubform(): NodeElement
+ {
+ $images = $this->getElement('images');
+ $imageSubforms = $images->findAll('css', '[data-test-image-subform]');
+
+ return reset($imageSubforms);
+ }
+
+ /*
+ * Helpers
+ */
+
+ private function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('form');
+ sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
+
+ private function clickButton(string $locator): void
+ {
+ $this->getDocument()->pressButton($locator);
+ }
+}
diff --git a/src/Sylius/Behat/Page/Admin/Product/IndexPage.php b/src/Sylius/Behat/Page/Admin/Product/IndexPage.php
index 661b8b5dc8..e1cd4625c7 100644
--- a/src/Sylius/Behat/Page/Admin/Product/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/IndexPage.php
@@ -61,7 +61,7 @@ class IndexPage extends CrudIndexPage implements IndexPageInterface
$table = $this->getElement('table');
$row = $tableAccessor->getRowWithFields($table, ['name' => $productName]);
$field = $tableAccessor->getFieldFromRow($table, $row, 'actions');
- $field->clickLink('Details');
+ $field->clickLink('details');
}
public function goToPage(int $page): void
diff --git a/src/Sylius/Behat/Page/Admin/Product/ShowPage.php b/src/Sylius/Behat/Page/Admin/Product/ShowPage.php
index d5bb4aa31d..8b91764bd7 100644
--- a/src/Sylius/Behat/Page/Admin/Product/ShowPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/ShowPage.php
@@ -26,7 +26,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function isShowInShopButtonDisabled(): bool
{
- return $this->getElement('show_product_single_button')->hasClass('disabled');
+ return $this->getElement('show_product_button')->hasClass('disabled');
}
public function getAppliedCatalogPromotionsLinks(string $variantName, string $channelName): array
@@ -60,12 +60,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
public function showProductInChannel(string $channel): void
{
- $this->getElement('show_product_dropdown')->clickLink($channel);
+ $this->getElement('show_product_button')->clickLink($channel);
}
public function showProductInSingleChannel(): void
{
- $this->getElement('show_product_single_button')->click();
+ $this->getElement('show_product_button')->click();
}
public function showProductEditPage(): void
@@ -81,13 +81,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
+ 'breadcrumb' => '.breadcrumb > div',
'edit_product_button' => '#edit-product',
'edit_variant_button' => '#variants .variants-accordion__title:contains("%variantCode%") .edit-variant',
'product_name' => '#header h1 .content > span',
- 'show_product_dropdown' => '.scrolling.menu',
- 'show_product_single_button' => '.ui.labeled.icon.button',
+ 'show_product_button' => '[data-test-view-in-store]',
'variants' => '#variants',
- 'breadcrumb' => '.breadcrumb > div',
]);
}
diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php
index 87c17ebad2..cb2f439adb 100644
--- a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php
@@ -14,25 +14,38 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Product;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
use Sylius\Behat\Service\AutocompleteHelper;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Taxonomy\Model\TaxonInterface;
+use Symfony\Component\Routing\RouterInterface;
use Webmozart\Assert\Assert;
class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConfigurableProductPageInterface
{
use ChecksCodeImmutability;
+ use FormTrait;
+
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
+ }
private array $imageUrls = [];
- public function nameItIn(string $name, string $localeCode): void
+ public function saveChanges(): void
{
- $this->getDocument()->fillField(
- sprintf('sylius_product_translations_%s_name', $localeCode),
- $name,
- );
+ $this->waitForFormUpdate();
+
+ parent::saveChanges();
}
public function setMetaKeywords(string $keywords, string $localeCode): void
@@ -105,91 +118,7 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf
public function hasLastImageAVariant(ProductVariantInterface $productVariant): bool
{
- $this->clickTabIfItsNotActive('media');
-
- $imageForm = $this->getLastImageElement();
-
- return $productVariant->getCode() === $imageForm->find('css', 'input[type="hidden"]')->getValue();
- }
-
- public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void
- {
- $this->clickTabIfItsNotActive('media');
- $this->getDocument()->clickLink('Add');
-
- $imageForm = $this->getLastImageElement();
-
- if (null !== $type) {
- $imageForm->fillField('Type', $type);
- }
-
- if (null !== $productVariant) {
- $imageForm->find('css', 'input[type="hidden"]')->setValue($productVariant->getCode());
- }
-
- $filesPath = $this->getParameter('files_path');
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function changeImageWithType(string $type, string $path): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $imageForm = $this->getImageElementByType($type);
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function removeImageWithType(string $type): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $imageElement = $this->getImageElementByType($type);
- $imageSourceElement = $imageElement->find('css', 'img');
- if (null !== $imageSourceElement) {
- $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src'));
- }
-
- $imageElement->clickLink('Delete');
- }
-
- public function removeFirstImage(): void
- {
- $this->clickTabIfItsNotActive('media');
- $imageElement = $this->getFirstImageElement();
- $imageTypeElement = $imageElement->find('css', 'input[type=text]');
- $imageSourceElement = $imageElement->find('css', 'img');
-
- if (null !== $imageTypeElement && null !== $imageSourceElement) {
- $this->saveImageUrlForType(
- $imageTypeElement->getValue(),
- $imageSourceElement->getAttribute('src'),
- );
- }
-
- $imageElement->clickLink('Delete');
- }
-
- public function modifyFirstImageType(string $type): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $firstImage = $this->getFirstImageElement();
- $this->setImageType($firstImage, $type);
- }
-
- public function selectVariantForFirstImage(ProductVariantInterface $productVariant): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $imageElement = $this->getFirstImageElement();
- $imageElement->find('css', 'input[type="hidden"]')->setValue($productVariant->getCode());
- }
-
- public function countImages(): int
- {
- $imageElements = $this->getImageElements();
-
- return count($imageElements);
+ return $this->hasImageWithVariant($productVariant);
}
public function goToVariantsList(): void
@@ -207,11 +136,6 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf
$this->getDocument()->clickLink('Generate');
}
- public function hasInventoryTab(): bool
- {
- return null !== $this->getDocument()->find('css', '.tab > h3:contains("Inventory")');
- }
-
protected function getCodeElement(): NodeElement
{
return $this->getElement('code');
@@ -219,20 +143,24 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'channel_checkbox' => '.checkbox:contains("%channel%") input',
- 'channels' => '#sylius_product_channels',
- 'code' => '#sylius_product_code',
- 'images' => '#sylius_product_images',
- 'main_taxon' => '#sylius_product_mainTaxon',
- 'name' => '#sylius_product_translations_en_US_name',
- 'options' => '#sylius_product_options',
- 'price' => '#sylius_product_variant_price',
- 'search' => '.ui.fluid.search.selection.dropdown',
- 'search_item_selected' => 'div.menu > div.item.selected',
- 'tab' => '.menu [data-tab="%name%"]',
- 'taxonomy' => 'a[data-tab="taxonomy"]',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ [
+ 'channel_checkbox' => '.checkbox:contains("%channel%") input',
+ 'channels' => '#sylius_product_channels',
+ 'code' => '#sylius_product_code',
+ 'images' => '#sylius_product_images',
+ 'main_taxon' => '#sylius_product_mainTaxon',
+ 'name' => '#sylius_product_translations_en_US_name',
+ 'options' => '#sylius_product_options',
+ 'price' => '#sylius_product_variant_price',
+ 'search' => '.ui.fluid.search.selection.dropdown',
+ 'search_item_selected' => 'div.menu > div.item.selected',
+ 'tab' => '.menu [data-tab="%name%"]',
+ 'taxonomy' => 'a[data-tab="taxonomy"]',
+ ],
+ $this->getDefinedFormElements(),
+ );
}
private function openTaxonBookmarks(): void
diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php
index 33deb9c193..9075890e36 100644
--- a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php
@@ -41,6 +41,8 @@ interface UpdateConfigurableProductPageInterface extends UpdatePageInterface
public function hasLastImageAVariant(ProductVariantInterface $productVariant): bool;
+ public function hasImageWithType(string $type): bool;
+
public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void;
public function changeImageWithType(string $type, string $path): void;
@@ -61,5 +63,5 @@ interface UpdateConfigurableProductPageInterface extends UpdatePageInterface
public function goToVariantGeneration(): void;
- public function hasInventoryTab(): bool;
+ public function hasTab(string $name): bool;
}
diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php
index 96c5b526e5..d275d8c286 100644
--- a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php
+++ b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php
@@ -14,34 +14,41 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Product;
use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
use Sylius\Behat\Service\AutocompleteHelper;
use Sylius\Behat\Service\DriverHelper;
+use Sylius\Behat\Service\Helper\AutocompleteHelperInterface;
use Sylius\Behat\Service\SlugGenerationHelper;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
-use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
+use Symfony\Component\Routing\RouterInterface;
use Webmozart\Assert\Assert;
class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProductPageInterface
{
use ChecksCodeImmutability;
+ use FormTrait;
+
+ public function __construct(
+ Session $session,
+ $minkParameters,
+ RouterInterface $router,
+ string $routeName,
+ private readonly AutocompleteHelperInterface $autocompleteHelper,
+ ) {
+ parent::__construct($session, $minkParameters, $router, $routeName);
+ }
private array $imageUrls = [];
- public function nameItIn(string $name, string $localeCode): void
+ public function saveChanges(): void
{
- $this->activateLanguageTab($localeCode);
- $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
+ $this->waitForFormUpdate();
- if (DriverHelper::isJavascript($this->getDriver())) {
- SlugGenerationHelper::waitForSlugGeneration(
- $this->getSession(),
- $this->getElement('slug', ['%locale%' => $localeCode]),
- );
- }
+ parent::saveChanges();
}
public function specifyPrice(ChannelInterface $channel, string $price): void
@@ -54,16 +61,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
$this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
}
- public function addSelectedAttributes(): void
- {
- $this->clickTabIfItsNotActive('attributes');
- $this->getDocument()->pressButton('Add attributes');
-
- $form = $this->getDocument()->find('css', 'form');
-
- $this->getDocument()->waitFor(1, fn () => $form->hasClass('loading'));
- }
-
public function removeAttribute(string $attributeName, string $localeCode): void
{
$this->clickTabIfItsNotActive('attributes');
@@ -71,13 +68,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
$this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '$localeCode%' => $localeCode])->press();
}
- public function getAttributeValue(string $attribute, string $localeCode): string
- {
- $this->clickTabIfItsNotActive('attributes');
-
- return $this->getElement('attribute', ['%attributeName%' => $attribute, '%localeCode%' => $localeCode])->getValue();
- }
-
public function getAttributeSelectText(string $attribute, string $localeCode): string
{
$this->clickTabIfItsNotActive('attributes');
@@ -101,11 +91,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
return $validationError->getText();
}
- public function getNumberOfAttributes(): int
- {
- return count($this->getDocument()->findAll('css', '.attribute'));
- }
-
public function hasAttribute(string $attributeName): bool
{
return null !== $this->getDocument()->find('css', sprintf('.attribute .label:contains("%s")', $attributeName));
@@ -230,74 +215,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
return in_array($statusCode, [200, 304], true);
}
- public function attachImage(string $path, ?string $type = null): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $filesPath = $this->getParameter('files_path');
-
- $this->getDocument()->clickLink('Add');
-
- $imageForm = $this->getLastImageElement();
- if (null !== $type) {
- $imageForm->fillField('Type', $type);
- }
-
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function changeImageWithType(string $type, string $path): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $imageForm = $this->getImageElementByType($type);
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function removeImageWithType(string $type): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $imageElement = $this->getImageElementByType($type);
- $imageSourceElement = $imageElement->find('css', 'img');
- if (null !== $imageSourceElement) {
- $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src'));
- }
-
- $imageElement->clickLink('Delete');
- }
-
- public function removeFirstImage(): void
- {
- $this->clickTabIfItsNotActive('media');
- $imageElement = $this->getFirstImageElement();
- $imageTypeElement = $imageElement->find('css', 'input[type=text]');
- $imageSourceElement = $imageElement->find('css', 'img');
-
- if (null !== $imageTypeElement && null !== $imageSourceElement) {
- $this->saveImageUrlForType(
- $imageTypeElement->getValue(),
- $imageSourceElement->getAttribute('src'),
- );
- }
- $imageElement->clickLink('Delete');
- }
-
- public function modifyFirstImageType(string $type): void
- {
- $this->clickTabIfItsNotActive('media');
-
- $firstImage = $this->getFirstImageElement();
- $this->setImageType($firstImage, $type);
- }
-
- public function countImages(): int
- {
- $imageElements = $this->getImageElements();
-
- return count($imageElements);
- }
-
public function isSlugReadonlyIn(string $locale): bool
{
return SlugGenerationHelper::isSlugReadonly(
@@ -306,53 +223,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
);
}
- public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void
- {
- $this->clickTab('associations');
-
- $dropdown = $this->getElement('association_dropdown', [
- '%association%' => $productAssociationType->getName(),
- ]);
- $dropdown->click();
-
- foreach ($productsNames as $productName) {
- $dropdown->waitFor(5, fn () => $this->hasElement('association_dropdown_item', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]));
-
- $item = $this->getElement('association_dropdown_item', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]);
- $item->click();
- }
- }
-
- public function hasAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): bool
- {
- $this->clickTabIfItsNotActive('associations');
-
- return $this->hasElement('association_dropdown_item', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]);
- }
-
- public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void
- {
- $this->clickTabIfItsNotActive('associations');
-
- $item = $this->getElement('association_dropdown_item_selected', [
- '%association%' => $productAssociationType->getName(),
- '%item%' => $productName,
- ]);
-
- $deleteIcon = $item->find('css', 'i.delete');
- Assert::notNull($deleteIcon);
- $deleteIcon->click();
- }
-
public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency): string
{
$priceConfigurationElement = $this->getElement('pricing_configuration');
@@ -398,11 +268,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
return $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->getValue();
}
- public function isShippingRequired(): bool
- {
- return $this->getElement('shipping_required')->isChecked();
- }
-
public function goToVariantsList(): void
{
$this->getDocument()->clickLink('List variants');
@@ -418,29 +283,24 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
$this->getDocument()->clickLink('Generate');
}
- public function hasInventoryTab(): bool
- {
- return null !== $this->getDocument()->find('css', '.tab > h3:contains("Inventory")');
- }
-
public function getShowProductInSingleChannelUrl(): string
{
- return $this->getElement('show_product_single_button')->getAttribute('href');
+ return $this->getElement('show_product_button')->getAttribute('href');
}
public function isShowInShopButtonDisabled(): bool
{
- return $this->getElement('show_product_single_button')->hasClass('disabled');
+ return $this->getElement('show_product_button')->hasClass('disabled');
}
public function showProductInChannel(string $channel): void
{
- $this->getElement('show_product_dropdown')->clickLink($channel);
+ $this->getElement('show_product_button')->clickLink($channel);
}
public function showProductInSingleChannel(): void
{
- $this->getElement('show_product_single_button')->click();
+ $this->getElement('show_product_button')->click();
}
public function disable(): void
@@ -479,39 +339,42 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
- 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
- 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
- 'attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input',
- 'attribute_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select',
- 'attribute_element' => '.attribute',
- 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button',
- 'code' => '#sylius_product_code',
- 'images' => '#sylius_product_images',
- 'language_tab' => '[data-locale="%locale%"] .title',
- 'locale_tab' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"]',
- 'name' => '#sylius_product_translations_%locale%_name',
- 'prices' => '#sylius_product_variant_channelPricings',
- 'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
- 'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
- 'pricing_configuration' => '#sylius_calculator_container',
- 'main_taxon' => '#sylius_product_mainTaxon',
- 'meta_description' => '#sylius_product_translations_%locale%_metaDescription',
- 'meta_keywords' => '#sylius_product_translations_%locale%_metaKeywords',
- 'non_translatable_attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input',
- 'product_taxon' => '#sylius-product-taxonomy-tree .item .header:contains("%taxonName%") input',
- 'product_taxons' => '#sylius_product_productTaxons',
- 'shipping_required' => '#sylius_product_variant_shippingRequired',
- 'show_product_dropdown' => '.scrolling.menu',
- 'show_product_single_button' => '[data-test-show-product-in-shop-page]',
- 'slug' => '#sylius_product_translations_%locale%_slug',
- 'tab' => '.menu [data-tab="%name%"]',
- 'taxonomy' => 'a[data-tab="taxonomy"]',
- 'tracked' => '#sylius_product_variant_tracked',
- 'toggle_slug_modification_button' => '[data-locale="%locale%"] .toggle-product-slug-modification',
- 'enabled' => '#sylius_product_enabled',
- ]);
+ return array_merge(
+ parent::getDefinedElements(),
+ [
+ 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
+ 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
+ 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
+ 'attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input',
+ 'attribute_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select',
+ 'attribute_element' => '.attribute',
+ 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button',
+ 'code' => '#sylius_product_code',
+ 'images' => '#sylius_product_images',
+ 'language_tab' => '[data-locale="%locale%"] .title',
+ 'locale_tab' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"]',
+ 'name' => '#sylius_product_translations_%locale%_name',
+ 'prices' => '#sylius_product_variant_channelPricings',
+ 'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
+ 'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
+ 'pricing_configuration' => '#sylius_calculator_container',
+ 'main_taxon' => '#sylius_product_mainTaxon',
+ 'meta_description' => '#sylius_product_translations_%locale%_metaDescription',
+ 'meta_keywords' => '#sylius_product_translations_%locale%_metaKeywords',
+ 'non_translatable_attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input',
+ 'product_taxon' => '#sylius-product-taxonomy-tree .item .header:contains("%taxonName%") input',
+ 'product_taxons' => '#sylius_product_productTaxons',
+ 'shipping_required' => '#sylius_product_variant_shippingRequired',
+ 'show_product_button' => '[data-test-view-in-store]',
+ 'slug' => '#sylius_product_translations_%locale%_slug',
+ 'tab' => '.menu [data-tab="%name%"]',
+ 'taxonomy' => 'a[data-tab="taxonomy"]',
+ 'tracked' => '#sylius_product_variant_tracked',
+ 'toggle_slug_modification_button' => '[data-locale="%locale%"] .toggle-product-slug-modification',
+ 'enabled' => '#sylius_product_enabled',
+ ],
+ $this->getDefinedFormElements(),
+ );
}
private function openTaxonBookmarks(): void
diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php
index aebe8fd92f..6e61960919 100644
--- a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php
@@ -15,6 +15,7 @@ namespace Sylius\Behat\Page\Admin\Product;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
@@ -71,6 +72,8 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
public function isImageWithTypeDisplayed(string $type): bool;
+ public function hasImageWithType(string $type): bool;
+
public function attachImage(string $path, ?string $type = null): void;
public function changeImageWithType(string $type, string $path): void;
@@ -88,9 +91,9 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
*/
public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void;
- public function hasAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): bool;
+ public function hasAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): bool;
- public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void;
+ public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void;
public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency): string;
@@ -112,7 +115,7 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
public function goToVariantGeneration(): void;
- public function hasInventoryTab(): bool;
+ public function hasTab(string $name): bool;
public function getShowProductInSingleChannelUrl(): string;
diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php
deleted file mode 100644
index 699e3f5f1b..0000000000
--- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php
+++ /dev/null
@@ -1,44 +0,0 @@
-getDocument()->fillField(
- sprintf('sylius_product_association_type_translations_%s_name', $language),
- $name,
- );
- }
-
- protected function getCodeElement(): NodeElement
- {
- return $this->getElement('code');
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_product_association_type_code',
- 'name' => '#sylius_product_association_type_translations_en_US_name',
- ]);
- }
-}
diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php
deleted file mode 100644
index 5942b52349..0000000000
--- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php
+++ /dev/null
@@ -1,23 +0,0 @@
-getDocument()->fillField(
- sprintf('sylius_product_association_type_translations_%s_name', $language),
- $name,
- );
- }
-
- public function nameIt($name): void
- {
- $this->getElement('name')->setValue($name);
- }
-
- protected function getCodeElement(): NodeElement
- {
- return $this->getElement('code');
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_product_association_type_code',
- 'name' => '#sylius_product_association_type_translations_en_US_name',
- ]);
- }
-}
diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php
deleted file mode 100644
index f073d45076..0000000000
--- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php
+++ /dev/null
@@ -1,23 +0,0 @@
-getDocument()->find('css', 'form[name="sylius_product_variant"]');
- if (null === $formElement) {
- throw new ElementNotFoundException($this->getSession(), 'Field element');
- }
+ $validationMessage = $this->getDocument()->find('css', '.alert.alert-danger.d-block');
- $validationMessage = $formElement->find('css', '.sylius-validation-error');
if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.alert.alert-danger.d-block');
}
return $validationMessage->getText();
@@ -91,7 +87,7 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
public function getPricesValidationMessage(): string
{
- return $this->getElement('prices_validation_message')->getText();
+ return $this->getElement('prices-body')->getText();
}
public function setShippingRequired(bool $isShippingRequired): void
@@ -120,7 +116,7 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
'shipping_required' => '#sylius_product_variant_shippingRequired',
'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice',
'price' => '#sylius_product_variant_channelPricings_%channelCode%_price',
- 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error',
+ 'prices-body' => '[data-test-product-channel-pricings-accordion-body]',
'weight' => '#sylius_product_variant_weight',
'width' => '#sylius_product_variant_width',
]);
diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php
index b541d5dd88..344d7575fb 100644
--- a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php
+++ b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php
@@ -16,78 +16,95 @@ namespace Sylius\Behat\Page\Admin\ProductVariant;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Exception\ElementNotFoundException;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
-use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Behat\Service\TabsHelper;
class GeneratePage extends SymfonyPage implements GeneratePageInterface
{
- public function generate(): void
- {
- $this->getDocument()->pressButton('Generate');
- }
-
- public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void
- {
- $this->getElement('price', ['%position%' => $nth, '%channelCode%' => $channel->getCode()])->setValue($price);
- }
-
- public function specifyCode(int $nth, string $code): void
- {
- $this->getDocument()->fillField(sprintf('sylius_product_generate_variants_variants_%s_code', $nth), $code);
- }
-
- public function removeVariant(int $nth): void
- {
- $item = $this->getDocument()->find('css', sprintf('div[data-form-collection-index="%s"]', $nth));
-
- $item->clickLink('Delete');
- }
-
public function getRouteName(): string
{
return 'sylius_admin_product_variant_generate';
}
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessage(string $element, int $position): string
+ public function specifyCode(int $nth, string $code): void
{
- $foundElement = $this->getElement($element, ['%position%' => $position]);
- $validatedField = $this->getValidatedField($foundElement);
-
- return $validatedField->find('css', '.sylius-validation-error')->getText();
+ $this->getElement('code', ['%position%' => $nth])->setValue($code);
}
- public function getPricesValidationMessage(int $position): string
+ public function specifyPrice(int $nth, int $price, string $channelCode): void
{
- return $this->getElement('prices_validation_message', ['%position%' => $position])->getText();
+ $channelPricing = $this->getElement('channel_pricings', ['%position%' => $nth]);
+
+ TabsHelper::switchTab($this->getSession(), $channelPricing, $channelCode);
+
+ $channelPricing->find('css', sprintf('[id$="_channelPricings_%s"]', $channelCode))->fillField('Price', $price);
+ }
+
+ public function generate(): void
+ {
+ $this->getElement('generate_button')->press();
+ }
+
+ public function removeVariant(int $nth): void
+ {
+ $this->getElement('delete_button', ['%position%' => $nth])->click();
+ $this->waitForFormUpdate();
+ }
+
+ public function getValidationMessage(string $element, int $position): string
+ {
+ $foundElement = $this->getFieldElement($element, ['%position%' => $position]);
+ if (null === $foundElement) {
+ throw new ElementNotFoundException($this->getSession(), 'Field element');
+ }
+
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
+ }
+
+ return $validationMessage->getText();
+ }
+
+ public function isGenerationPossible(): bool
+ {
+ return !$this->getElement('generate_button')->hasAttribute('disabled');
+ }
+
+ public function isProductVariantRemovable(int $nth): bool
+ {
+ return $this->hasElement('delete_button', ['%position%' => $nth]);
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_product_generate_variants_variants_%position%_code',
- 'price' => '#sylius_product_generate_variants_variants_%position%_channelPricings_%channelCode% input[id*="%channelCode%"]',
- 'prices_validation_message' => 'div[data-form-collection-index="%position%"] div.tabular.menu ~ .sylius-validation-error',
+ 'generate_button' => '[data-test-generate-button]',
+ 'delete_button' => '#sylius_product_generate_variants_variants_%position% [data-test-delete-button]',
+ 'code' => '#sylius_product_generate_variants_variants_%position% [data-test-code]',
+ 'channel_pricings' => '#sylius_product_generate_variants_variants_%position% [data-test-channel-pricings]',
+ 'form' => '[data-live-name-value="sylius_admin:product:generate_product_variants_form"]',
]);
}
+ private function waitForFormUpdate(): void
+ {
+ $form = $this->getElement('form');
+ sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute
+ $form->waitFor(1500, function () use ($form) {
+ return !$form->hasAttribute('busy');
+ });
+ }
+
/**
* @throws ElementNotFoundException
*/
- private function getValidatedField(NodeElement $element): NodeElement
+ private function getFieldElement(string $element, array $parameters = []): ?NodeElement
{
+ $element = $this->getElement($element, $parameters);
while (null !== $element && !$element->hasClass('field')) {
$element = $element->getParent();
}
return $element;
}
-
- public function isGenerationPossible(): bool
- {
- $generateButton = $this->getDocument()->find('css', 'button:contains("Generate")');
-
- return !$generateButton->hasAttribute('disabled');
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php
index 3bce79d52d..2bc9fa72c1 100644
--- a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php
@@ -14,13 +14,12 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ProductVariant;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
-use Sylius\Component\Core\Model\ChannelInterface;
interface GeneratePageInterface extends SymfonyPageInterface
{
public function generate(): void;
- public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void;
+ public function specifyPrice(int $nth, int $price, string $channelCode): void;
public function specifyCode(int $nth, string $code): void;
@@ -28,7 +27,7 @@ interface GeneratePageInterface extends SymfonyPageInterface
public function getValidationMessage(string $element, int $position): string;
- public function getPricesValidationMessage(int $position): string;
-
public function isGenerationPossible(): bool;
+
+ public function isProductVariantRemovable(int $nth): bool;
}
diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php b/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php
index 90643c6ddf..666ab50e5d 100644
--- a/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php
@@ -55,15 +55,15 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface
public function countItemsWithNoName(): int
{
- return count($this->getElement('table')->findAll('css', '[data-test-missing-translation-paragraph]'));
+ return count($this->getElement('table')->findAll('css', '[data-test-missing-translation]'));
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
- 'on_hand_quantity' => '.onHand[data-product-variant-id="%id%"]',
- 'on_hold_quantity' => '.onHold[data-product-variant-id="%id%"]',
- 'save_configuration_button' => '.sylius-save-position',
+ 'on_hand_quantity' => '[data-test-on-hand][data-product-variant-id="%id%"]',
+ 'on_hold_quantity' => '[data-test-on-hold][data-product-variant-id="%id%"]',
+ 'save_configuration_button' => '[data-test-save-configuration-button]',
]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
index 7347b83199..4c735f2970 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php
@@ -18,249 +18,44 @@ use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Behaviour\NamesIt;
use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
-use Sylius\Behat\Service\AutocompleteHelper;
-use Sylius\Behat\Service\TabsHelper;
-use Webmozart\Assert\Assert;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
use NamesIt;
use SpecifiesItsField;
- public function specifyLabel(string $label, string $localeCode): void
+ public function getValidationMessage(string $element): string
{
- $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click();
-
- $this->getDocument()->fillField(sprintf('sylius_promotion_translations_%s_label', $localeCode), $label);
- }
-
- public function addRule(?string $ruleName): void
- {
- $count = count($this->getCollectionItems('rules'));
-
- $this->getDocument()->clickLink('Add rule');
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('rules')));
-
- if (null !== $ruleName) {
- $this->selectRuleOption('Type', $ruleName);
- }
- }
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void
- {
- $this->getLastCollectionItem('rules')->find('named', ['select', $option])->selectOption($value, $multiple);
- }
-
- public function selectAutocompleteRuleOption(string $option, $value, bool $multiple = false): void
- {
- $option = strtolower(str_replace(' ', '_', $option));
-
- $ruleAutocomplete = $this
- ->getLastCollectionItem('rules')
- ->find('css', sprintf('input[type="hidden"][name*="[%s]"]', $option))
- ->getParent()
- ;
-
- if ($multiple && is_array($value)) {
- AutocompleteHelper::chooseValues($this->getSession(), $ruleAutocomplete, $value);
-
- return;
- }
-
- AutocompleteHelper::chooseValue($this->getSession(), $ruleAutocomplete, $value);
- }
-
- public function fillRuleOption(string $option, string $value): void
- {
- $this->getLastCollectionItem('rules')->fillField($option, $value);
- }
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void
- {
- $lastAction = $this->getChannelConfigurationOfLastRule($channelCode);
- $lastAction->fillField($option, $value);
- }
-
- public function addAction(?string $actionName): void
- {
- $count = count($this->getCollectionItems('actions'));
-
- $this->getDocument()->clickLink('Add action');
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('actions')));
-
- if (null !== $actionName) {
- $this->selectActionOption('Type', $actionName);
- }
- }
-
- public function selectActionOption(string $option, string $value, bool $multiple = false): void
- {
- $this->getLastCollectionItem('actions')->find('named', ['select', $option])->selectOption($value, $multiple);
- }
-
- public function fillActionOption(string $option, string $value): void
- {
- $this->getLastCollectionItem('actions')->fillField($option, $value);
- }
-
- public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void
- {
- $lastAction = $this->getChannelConfigurationOfLastAction($channelCode);
- $lastAction->fillField($option, $value);
- }
-
- public function fillUsageLimit(string $limit): void
- {
- $this->getDocument()->fillField('Usage limit', $limit);
- }
-
- public function makeExclusive(): void
- {
- $this->getDocument()->checkField('Exclusive');
- }
-
- public function makeNotAppliesToDiscountedItem(): void
- {
- $this->getDocument()->unCheckField('Applies to already discounted order items');
- }
-
- public function checkCouponBased(): void
- {
- $this->getDocument()->checkField('Coupon based');
- }
-
- public function checkChannel(string $name): void
- {
- $this->getDocument()->checkField($name);
- }
-
- public function setStartsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp));
- }
-
- public function setEndsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp));
- }
-
- public function getValidationMessageForAction(): string
- {
- $actionForm = $this->getLastCollectionItem('actions');
-
- $foundElement = $actionForm->find('css', '.sylius-validation-error');
+ $foundElement = $this->getFieldElement($element);
if (null === $foundElement) {
- throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
+ throw new ElementNotFoundException($this->getSession(), 'Field element');
}
- return $foundElement->getText();
- }
-
- public function selectAutoCompleteFilterOption(string $option, $value, bool $multiple = false): void
- {
- $option = strtolower(str_replace(' ', '_', $option));
-
- $filterAutocomplete = $this
- ->getLastCollectionItem('actions')
- ->find('css', sprintf('input[type="hidden"][name*="[%s_filter]"]', $option))
- ->getParent()
- ;
-
- if ($multiple && is_array($value)) {
- AutocompleteHelper::chooseValues($this->getSession(), $filterAutocomplete, $value);
-
- return;
+ $validationMessage = $foundElement->find('css', '.invalid-feedback');
+ if (null === $validationMessage) {
+ throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback');
}
- AutocompleteHelper::chooseValue($this->getSession(), $filterAutocomplete, $value);
- }
-
- public function checkIfRuleConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('count');
- }
-
- public function checkIfActionConfigurationFormIsVisible(): bool
- {
- return $this->hasElement('amount');
- }
-
- public function hasLabel(string $label, string $localeCode): bool
- {
- $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click();
-
- $labelElement = $this->getDocument()->find('css', sprintf('label:contains("%s")', $label));
- if (null === $labelElement) {
- return false;
- }
-
- return $labelElement->hasClass(sprintf('sylius-locale-%s', $localeCode));
+ return $validationMessage->getText();
}
protected function getDefinedElements(): array
{
- return [
- 'actions' => '#sylius_promotion_actions',
+ return array_merge(parent::getDefinedElements(), [
'code' => '#sylius_promotion_code',
- 'ends_at' => '#sylius_promotion_endsAt',
- 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min',
- 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max',
- 'name' => '#sylius_promotion_name',
+ 'form' => '[data-live-name-value="sylius_admin:promotion:form"]',
'rules' => '#sylius_promotion_rules',
- 'starts_at' => '#sylius_promotion_startsAt',
- 'count' => '#sylius_promotion_rules_0_configuration_count',
- 'amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount',
- ];
+ ]);
}
- private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement
+ /** @throws ElementNotFoundException */
+ private function getFieldElement(string $element): ?NodeElement
{
- $lastAction = $this->getLastCollectionItem('actions');
+ $element = $this->getElement($element);
+ while (null !== $element && !$element->hasClass('field')) {
+ $element = $element->getParent();
+ }
- TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode);
-
- return $lastAction
- ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode))
- ;
- }
-
- private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement
- {
- $lastRule = $this->getLastCollectionItem('rules');
-
- TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode);
-
- return $lastRule
- ->find('css', sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode))
- ;
- }
-
- private function getLastCollectionItem(string $collection): NodeElement
- {
- $items = $this->getCollectionItems($collection);
-
- Assert::notEmpty($items);
-
- return end($items);
- }
-
- /**
- * @return NodeElement[]
- */
- private function getCollectionItems(string $collection): array
- {
- $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]');
-
- Assert::isArray($items);
-
- return $items;
+ return $element;
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
index 30a0fb094a..c1102bfd66 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php
@@ -13,65 +13,13 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Promotion;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
public function specifyCode(string $code): void;
- public function specifyLabel(string $label, string $localeCode): void;
-
public function nameIt(string $name): void;
- public function addRule(?string $ruleName): void;
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void;
-
- /**
- * @param string|string[] $value
- */
- public function selectAutocompleteRuleOption(string $option, array|string $value, bool $multiple = false): void;
-
- public function fillRuleOption(string $option, string $value): void;
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void;
-
- public function addAction(?string $actionName): void;
-
- public function selectActionOption(string $option, string $value, bool $multiple = false): void;
-
- public function fillActionOption(string $option, string $value): void;
-
- public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void;
-
- public function fillUsageLimit(string $limit): void;
-
- public function makeExclusive(): void;
-
- public function makeNotAppliesToDiscountedItem(): void;
-
- public function checkCouponBased(): void;
-
- public function checkChannel(string $name): void;
-
- public function setStartsAt(\DateTimeInterface $dateTime): void;
-
- public function setEndsAt(\DateTimeInterface $dateTime): void;
-
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForAction(): string;
-
- /**
- * @param string|string[] $value
- */
- public function selectAutoCompleteFilterOption(string $option, array|string $value, bool $multiple = false): void;
-
- public function checkIfRuleConfigurationFormIsVisible(): bool;
-
- public function checkIfActionConfigurationFormIsVisible(): bool;
-
- public function hasLabel(string $label, string $localeCode): bool;
+ public function getValidationMessage(string $element): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
index f9072e2889..ec46e6cf4e 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php
@@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Promotion;
use Behat\Mink\Element\NodeElement;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
use Sylius\Behat\Behaviour\CountsChannelBasedErrors;
use Sylius\Behat\Behaviour\NamesIt;
@@ -26,16 +25,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
use CountsChannelBasedErrors;
use NamesIt;
- public function setPriority(?int $priority): void
- {
- $this->getDocument()->fillField('Priority', $priority);
- }
-
- public function getPriority(): int
- {
- return (int) $this->getElement('priority')->getValue();
- }
-
public function checkChannelsState(string $channelName): bool
{
$field = $this->getDocument()->findField($channelName);
@@ -43,42 +32,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return (bool) $field->getValue();
}
- public function fillUsageLimit(string $limit): void
- {
- $this->getDocument()->fillField('Usage limit', $limit);
- }
-
- public function makeExclusive(): void
- {
- $this->getDocument()->checkField('Exclusive');
- }
-
- public function checkCouponBased(): void
- {
- $this->getDocument()->checkField('Coupon based');
- }
-
- public function checkChannel(string $name): void
- {
- $this->getDocument()->checkField($name);
- }
-
- public function setStartsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp));
- }
-
- public function setEndsAt(\DateTimeInterface $dateTime): void
- {
- $timestamp = $dateTime->getTimestamp();
-
- $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp));
- $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp));
- }
-
public function hasStartsAt(\DateTimeInterface $dateTime): bool
{
$timestamp = $dateTime->getTimestamp();
@@ -167,21 +120,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $this->countChannelErrors($this->getElement('rules'), $channelCode);
}
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForTranslation(string $element, string $localeCode): string
- {
- $foundElement = $this->getElement($element, ['%localeCode%' => $localeCode])->getParent();
-
- $validationMessage = $foundElement->find('css', '.sylius-validation-error');
- if (null === $validationMessage) {
- throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error');
- }
-
- return $validationMessage->getText();
- }
-
protected function getCodeElement(): NodeElement
{
return $this->getElement('code');
@@ -189,26 +127,25 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
protected function getDefinedElements(): array
{
- return [
+ return array_merge(parent::getDefinedElements(), [
'action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_%channelCode%_%field%"]',
'actions' => '#actions',
'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted',
'code' => '#sylius_promotion_code',
- 'coupon_based' => '#sylius_promotion_couponBased',
'ends_at' => '#sylius_promotion_endsAt',
'ends_at_date' => '#sylius_promotion_endsAt_date',
'ends_at_time' => '#sylius_promotion_endsAt_time',
'exclusive' => '#sylius_promotion_exclusive',
- 'label' => '#sylius_promotion_translations_%localeCode%_label',
+ 'coupon_based' => '#sylius_promotion_couponBased',
'name' => '#sylius_promotion_name',
'order_percentage_action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_percentage"]',
'priority' => '#sylius_promotion_priority',
'rule_amount' => '[id^="sylius_promotion_rules_"][id$="_configuration_%channelCode%_amount"]',
'rules' => '#rules',
+ 'usage_limit' => '#sylius_promotion_usageLimit',
'starts_at' => '#sylius_promotion_startsAt',
'starts_at_date' => '#sylius_promotion_startsAt_date',
'starts_at_time' => '#sylius_promotion_startsAt_time',
- 'usage_limit' => '#sylius_promotion_usageLimit',
- ];
+ ]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
index 3f3804b1ff..be0d90f967 100644
--- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php
@@ -13,33 +13,16 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Promotion;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
interface UpdatePageInterface extends BaseUpdatePageInterface
{
- public function setPriority(?int $priority): void;
-
- public function getPriority(): int;
-
public function nameIt(string $name): void;
public function checkChannelsState(string $channelName): bool;
public function isCodeDisabled(): bool;
- public function fillUsageLimit(string $limit): void;
-
- public function makeExclusive(): void;
-
- public function checkCouponBased(): void;
-
- public function checkChannel(string $name): void;
-
- public function setStartsAt(\DateTimeInterface $dateTime): void;
-
- public function setEndsAt(\DateTimeInterface $dateTime): void;
-
public function hasStartsAt(\DateTimeInterface $dateTime): bool;
public function hasEndsAt(\DateTimeInterface $dateTime): bool;
@@ -65,9 +48,4 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function getActionValidationErrorsCount(string $channelCode): int;
public function getRuleValidationErrorsCount(string $channelCode): int;
-
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForTranslation(string $element, string $localeCode): string;
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php
index 946d71f8f7..b19b8e74a6 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php
@@ -13,179 +13,8 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
-use Behat\Mink\Element\NodeElement;
-use Behat\Mink\Exception\ElementNotFoundException;
-use Sylius\Behat\Behaviour\SpecifiesItsField;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
-use Sylius\Behat\Service\DriverHelper;
-use Sylius\Behat\Service\TabsHelper;
-use Sylius\Component\Core\Formatter\StringInflector;
-use Webmozart\Assert\Assert;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
- use SpecifiesItsField;
-
- public function specifyPosition(?int $position): void
- {
- $this->getDocument()->fillField('Position', $position);
- }
-
- public function nameIt(string $name, string $language): void
- {
- $this->getDocument()->fillField(sprintf('sylius_shipping_method_translations_%s_name', $language), $name);
- }
-
- public function describeIt(string $description, string $languageCode): void
- {
- $this->getDocument()->fillField(
- sprintf('sylius_shipping_method_translations_%s_description', $languageCode),
- $description,
- );
- }
-
- public function specifyAmountForChannel(string $channelCode, string $amount): void
- {
- TabsHelper::switchTab($this->getSession(), $this->getElement('calculator_configuration'), $channelCode);
-
- $this->getElement('amount', ['%channelCode%' => $channelCode])->setValue($amount);
- }
-
- public function chooseZone(string $name): void
- {
- $this->getDocument()->selectFieldOption('Zone', $name);
- }
-
- public function chooseCalculator(string $name): void
- {
- $this->getDocument()->selectFieldOption('Calculator', $name);
- }
-
- public function checkChannel($channelName): void
- {
- if (DriverHelper::isJavascript($this->getDriver())) {
- $this->getElement('channel', ['%channel%' => $channelName])->click();
-
- return;
- }
-
- $this->getDocument()->checkField($channelName);
- }
-
- public function getValidationMessageForAmount(string $channelCode): string
- {
- $foundElement = $this->getFieldElement('amount', ['%channelCode%' => $channelCode]);
-
- return $this->getValidationMessageForElement($foundElement);
- }
-
- public function getValidationMessageForRuleAmount(string $channelCode): string
- {
- $foundElement = $this->getChannelConfigurationOfLastRule($channelCode);
-
- return $this->getValidationMessageForElement($foundElement);
- }
-
- public function addRule(string $ruleName): void
- {
- $count = count($this->getCollectionItems('rules'));
-
- $this->getDocument()->clickLink('Add rule');
-
- $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('rules')));
-
- $this->selectRuleOption('Type', $ruleName);
- }
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void
- {
- $this->getLastCollectionItem('rules')->find('named', ['select', $option])->selectOption($value, $multiple);
- }
-
- public function fillRuleOption(string $option, string $value): void
- {
- $this->getLastCollectionItem('rules')->fillField($option, $value);
- }
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void
- {
- $lastAction = $this->getChannelConfigurationOfLastRule($channelCode);
- $lastAction->fillField($option, $value);
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'amount' => '#sylius_shipping_method_configuration_%channelCode%_amount',
- 'channel' => '#sylius_shipping_method_channels .ui.checkbox:contains("%channel%")',
- 'calculator' => '#sylius_shipping_method_calculator',
- 'calculator_configuration' => '.ui.segment.configuration',
- 'weight' => '[id*="sylius_shipping_method_rules_"][id*="_configuration_weight"]',
- 'code' => '#sylius_shipping_method_code',
- 'name' => '#sylius_shipping_method_translations_en_US_name',
- 'zone' => '#sylius_shipping_method_zone',
- 'rules' => '#sylius_shipping_method_rules',
- ]);
- }
-
- private function getValidationMessageForElement(NodeElement $element): string
- {
- if (null === $element) {
- throw new ElementNotFoundException($this->getSession(), 'Field element');
- }
-
- $validationMessage = $element->find('css', '.sylius-validation-error');
- if (null === $validationMessage) {
- throw new ElementNotFoundException(
- $this->getSession(),
- 'Validation message',
- 'css',
- '.sylius-validation-error',
- );
- }
-
- return $validationMessage->getText();
- }
-
- /**
- * @throws ElementNotFoundException
- */
- private function getFieldElement(string $element, array $parameters = []): ?NodeElement
- {
- $element = $this->getElement(StringInflector::nameToCode($element), $parameters);
- while (null !== $element && !$element->hasClass('field')) {
- $element = $element->getParent();
- }
-
- return $element;
- }
-
- private function getLastCollectionItem(string $collection): NodeElement
- {
- $items = $this->getCollectionItems($collection);
-
- Assert::notEmpty($items);
-
- return end($items);
- }
-
- /**
- * @return NodeElement[]
- */
- private function getCollectionItems(string $collection): array
- {
- $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]');
-
- Assert::isArray($items);
-
- return $items;
- }
-
- private function getChannelConfigurationOfLastRule(string $channelCode): ?NodeElement
- {
- return $this
- ->getLastCollectionItem('rules')
- ->find('css', sprintf('[id^="sylius_shipping_method_rules_"][id$="_configuration_%s"]', $channelCode))
- ;
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php
index aee0845836..6655e45406 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php
@@ -13,38 +13,8 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
- public function specifyCode(string $code): void;
-
- public function specifyPosition(?int $position): void;
-
- public function nameIt(string $name, string $language): void;
-
- public function describeIt(string $description, string $languageCode): void;
-
- public function specifyAmountForChannel(string $channelCode, string $amount): void;
-
- public function chooseZone(string $name): void;
-
- public function chooseCalculator(string $name): void;
-
- public function checkChannel(string $channelName): void;
-
- /** @throws ElementNotFoundException */
- public function getValidationMessageForAmount(string $channelCode): string;
-
- /** @throws ElementNotFoundException */
- public function getValidationMessageForRuleAmount(string $channelCode): string;
-
- public function addRule(string $ruleName): void;
-
- public function selectRuleOption(string $option, string $value, bool $multiple = false): void;
-
- public function fillRuleOption(string $option, string $value): void;
-
- public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php
index 193d85483d..9a2e91f199 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php
@@ -13,12 +13,19 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
+use Behat\Mink\Element\NodeElement;
use Sylius\Behat\Page\Admin\Crud\IndexPage as BaseIndexPage;
+use Sylius\Component\Core\Model\ShippingMethodInterface;
+use Sylius\Component\Resource\Model\ResourceInterface;
class IndexPage extends BaseIndexPage implements IndexPageInterface
{
public function chooseArchival(string $isArchival): void
{
+ if (!$this->areFiltersVisible()) {
+ $this->toggleFilters();
+ }
+
$this->getElement('filter_archival')->selectOption($isArchival);
}
@@ -29,10 +36,52 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface
return null !== $archival;
}
+ public function archiveShippingMethod(string $name): void
+ {
+ $actions = $this->getActionsForResource(['name' => $name]);
+ $actions->pressButton('archive');
+ $this->getElement('confirm_action_button')->press();
+ }
+
+ public function deleteShippingMethod(string $name): void
+ {
+ $this->open();
+ $this->deleteResourceOnPage(['name' => $name]);
+ $this->getElement('confirm_action_button')->press();
+ }
+
+ public function restoreShippingMethod(string $name): void
+ {
+ $actions = $this->getActionsForResource(['name' => $name]);
+ $actions->pressButton('Restore');
+ $this->getElement('confirm_action_button')->press();
+ }
+
+ public function isShippingMethodDisabled(ShippingMethodInterface $shippingMethod): bool
+ {
+ $this->open();
+
+ return null !== $this->getRowFor($shippingMethod)->find('css', '[data-test-status-disabled]');
+ }
+
+ public function isShippingMethodEnabled(ShippingMethodInterface $shippingMethod): bool
+ {
+ $this->open();
+
+ return null !== $this->getRowFor($shippingMethod)->find('css', '[data-test-status-enabled]');
+ }
+
+ private function getRowFor(ResourceInterface $shippingMethod): NodeElement
+ {
+ return $this->getElement('row', ['%resourceId%' => $shippingMethod->getId()]);
+ }
+
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
+ 'confirm_action_button' => '[data-confirm-btn-true]',
'filter_archival' => '#criteria_archival',
+ 'row' => '[data-test-row][data-test-resource-id="%resourceId%"]',
]);
}
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php
index b476112a23..3f9527a1be 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php
@@ -14,10 +14,21 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface as BaseIndexPageInterface;
+use Sylius\Component\Core\Model\ShippingMethodInterface;
interface IndexPageInterface extends BaseIndexPageInterface
{
public function chooseArchival(string $isArchival): void;
public function isArchivalFilterEnabled(): bool;
+
+ public function archiveShippingMethod(string $name): void;
+
+ public function deleteShippingMethod(string $name): void;
+
+ public function restoreShippingMethod(string $name): void;
+
+ public function isShippingMethodEnabled(ShippingMethodInterface $shippingMethod): bool;
+
+ public function isShippingMethodDisabled(ShippingMethodInterface $shippingMethod): bool;
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php
index 0e3b75f4b9..45a4022c4c 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php
@@ -13,65 +13,8 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
-use Behat\Mink\Element\NodeElement;
-use Sylius\Behat\Behaviour\ChecksCodeImmutability;
-use Sylius\Behat\Behaviour\CountsChannelBasedErrors;
-use Sylius\Behat\Behaviour\Toggles;
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
{
- use ChecksCodeImmutability;
- use CountsChannelBasedErrors;
- use Toggles;
-
- public function isAvailableInChannel(string $channelName): bool
- {
- return $this->getElement('channel', ['%channel%' => $channelName])->hasAttribute('checked');
- }
-
- public function removeZone(): void
- {
- $this->getDocument()->selectFieldOption('Zone', 'Select');
- }
-
- public function removeShippingChargesAmount(string $channelCode): void
- {
- $this->getElement('amount', ['%channelCode%' => $channelCode])->setValue('');
- }
-
- public function getValidationMessageForAmount(string $channelCode): string
- {
- $foundElement = $this->getElement('amount', ['%channelCode%' => $channelCode]);
-
- return $foundElement->find('css', '.sylius-validation-error')->getText();
- }
-
- public function getShippingChargesValidationErrorsCount(string $channelCode): int
- {
- return $this->countChannelErrors($this->getElement('shipping_charges'), $channelCode);
- }
-
- protected function getCodeElement(): NodeElement
- {
- return $this->getElement('code');
- }
-
- protected function getToggleableElement(): NodeElement
- {
- return $this->getElement('enabled');
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'amount' => '#sylius_shipping_method_configuration_%channelCode%_amount',
- 'channel' => '.checkbox:contains("%channel%") input',
- 'code' => '#sylius_shipping_method_code',
- 'enabled' => '#sylius_shipping_method_enabled',
- 'name' => '#sylius_shipping_method_translations_en_US_name',
- 'shipping_charges' => '.ui.segment.configuration',
- 'zone' => '#sylius_shipping_method_zone',
- ]);
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php
index b726c4115c..4638f88ab5 100644
--- a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php
@@ -13,27 +13,8 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ShippingMethod;
-use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
interface UpdatePageInterface extends BaseUpdatePageInterface
{
- public function isCodeDisabled(): bool;
-
- public function isAvailableInChannel(string $channelName): bool;
-
- public function enable(): void;
-
- public function disable(): void;
-
- public function removeZone(): void;
-
- public function removeShippingChargesAmount(string $channelCode): void;
-
- /**
- * @throws ElementNotFoundException
- */
- public function getValidationMessageForAmount(string $channelCode): string;
-
- public function getShippingChargesValidationErrorsCount(string $channelCode): int;
}
diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php
index 9b25c87011..d4b0dab873 100644
--- a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php
@@ -21,61 +21,15 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
{
use NamesIt;
use SpecifiesItsField;
-
- public function chooseZone(string $name): void
- {
- $this->getDocument()->selectFieldOption('Zone', $name);
- }
-
- public function chooseCategory(string $name): void
- {
- $this->getDocument()->selectFieldOption('Category', $name);
- }
-
- public function chooseCalculator(string $name): void
- {
- $this->getDocument()->selectFieldOption('Calculator', $name);
- }
-
- public function specifyAmount(string $amount): void
- {
- $this->getDocument()->fillField('Amount', $amount);
- }
-
- public function specifyStartDate(\DateTimeInterface $startDate): void
- {
- $timestamp = $startDate->getTimestamp();
-
- $this->getElement('start_date')->setValue(date('Y-m-d', $timestamp));
- $this->getElement('start_date_time')->setValue(date('H:i', $timestamp));
- }
-
- public function specifyEndDate(\DateTimeInterface $endDate): void
- {
- $timestamp = $endDate->getTimestamp();
-
- $this->getElement('end_date')->setValue(date('Y-m-d', $timestamp));
- $this->getElement('end_date_time')->setValue(date('H:i', $timestamp));
- }
+ use FormAwareTrait;
public function chooseIncludedInPrice(): void
{
- $this->getDocument()->find('css', 'label[for=sylius_tax_rate_includedInPrice]')->click();
+ $this->getElement('field_included_in_price')->check();
}
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'amount' => '#sylius_tax_rate_amount',
- 'calculator' => '#sylius_tax_rate_calculator',
- 'category' => '#sylius_tax_rate_category',
- 'code' => '#sylius_tax_rate_code',
- 'end_date' => '#sylius_tax_rate_endDate_date',
- 'end_date_time' => '#sylius_tax_rate_endDate_time',
- 'name' => '#sylius_tax_rate_name',
- 'start_date' => '#sylius_tax_rate_startDate_date',
- 'start_date_time' => '#sylius_tax_rate_startDate_time',
- 'zone' => '#sylius_tax_rate_zone',
- ]);
+ return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements());
}
}
diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php
index 324e3d6f2c..e9374a988a 100644
--- a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php
@@ -15,23 +15,9 @@ namespace Sylius\Behat\Page\Admin\TaxRate;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
-interface CreatePageInterface extends BaseCreatePageInterface
+interface CreatePageInterface extends BaseCreatePageInterface, FormAwareInterface
{
public function specifyCode(string $code): void;
- public function nameIt(string $name): void;
-
- public function specifyAmount(string $amount): void;
-
- public function specifyStartDate(\DateTimeInterface $startDate): void;
-
- public function specifyEndDate(\DateTimeInterface $endDate): void;
-
- public function chooseZone(string $name): void;
-
- public function chooseCategory(string $name): void;
-
- public function chooseCalculator(string $name): void;
-
public function chooseIncludedInPrice(): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php
new file mode 100644
index 0000000000..67d2ad696f
--- /dev/null
+++ b/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php
@@ -0,0 +1,31 @@
+getElement('field_zone')->selectOption($name);
+ }
+
+ public function chooseCategory(string $name): void
+ {
+ $this->getElement('field_category')->selectOption($name);
+ }
+
+ public function chooseCalculator(string $name): void
+ {
+ $this->getElement('field_calculator')->selectOption($name);
+ }
+
+ public function specifyAmount(string $amount): void
+ {
+ $this->getElement('field_amount')->setValue($amount);
+ }
+
+ public function specifyStartDate(\DateTimeInterface $startDate): void
+ {
+ $timestamp = $startDate->getTimestamp();
+
+ $this->getElement('field_start_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('field_start_date_time')->setValue(date('H:i', $timestamp));
+ }
+
+ public function specifyEndDate(\DateTimeInterface $endDate): void
+ {
+ $timestamp = $endDate->getTimestamp();
+
+ $this->getElement('field_end_date')->setValue(date('Y-m-d', $timestamp));
+ $this->getElement('field_end_date_time')->setValue(date('H:i', $timestamp));
+ }
+
+ /** @return array */
+ protected function getDefinedFormElements(): array
+ {
+ return [
+ 'field_amount' => '#sylius_tax_rate_amount',
+ 'field_calculator' => '#sylius_tax_rate_calculator',
+ 'field_category' => '#sylius_tax_rate_category',
+ 'field_code' => '#sylius_tax_rate_code',
+ 'field_end_date' => '#sylius_tax_rate_endDate_date',
+ 'field_end_date_time' => '#sylius_tax_rate_endDate_time',
+ 'field_included_in_price' => '#sylius_tax_rate_includedInPrice',
+ 'field_name' => '#sylius_tax_rate_name',
+ 'field_start_date' => '#sylius_tax_rate_startDate_date',
+ 'field_start_date_time' => '#sylius_tax_rate_startDate_time',
+ 'field_zone' => '#sylius_tax_rate_zone',
+ ];
+ }
+}
diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php
index dbe3860bb6..24a8a08315 100644
--- a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php
@@ -19,33 +19,26 @@ use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
{
+ use FormAwareTrait;
use ChecksCodeImmutability;
public function removeZone(): void
{
- $this->getDocument()->selectFieldOption('Zone', 'Select');
+ $this->getElement('field_zone')->setValue('');
}
public function isIncludedInPrice(): bool
{
- return (bool) $this->getElement('included_in_price')->getValue();
+ return $this->getElement('field_included_in_price')->isChecked();
}
protected function getCodeElement(): NodeElement
{
- return $this->getElement('code');
+ return $this->getElement('field_code');
}
protected function getDefinedElements(): array
{
- return array_merge(parent::getDefinedElements(), [
- 'amount' => '#sylius_tax_rate_amount',
- 'calculator' => '#sylius_tax_rate_calculator',
- 'category' => '#sylius_tax_rate_category',
- 'code' => '#sylius_tax_rate_code',
- 'name' => '#sylius_tax_rate_name',
- 'zone' => '#sylius_tax_rate_zone',
- 'included_in_price' => '#sylius_tax_rate_includedInPrice',
- ]);
+ return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements());
}
}
diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php
index d08c49b492..b8fd6c860f 100644
--- a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php
@@ -15,9 +15,11 @@ namespace Sylius\Behat\Page\Admin\TaxRate;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
-interface UpdatePageInterface extends BaseUpdatePageInterface
+interface UpdatePageInterface extends BaseUpdatePageInterface, FormAwareInterface
{
public function isCodeDisabled(): bool;
+ public function isIncludedInPrice(): bool;
+
public function removeZone(): void;
}
diff --git a/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php b/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php
index 4027cbaf2f..1448fea15f 100644
--- a/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php
@@ -73,35 +73,6 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
return 0 !== $this->countTaxonsByName($name);
}
- public function nameIt(string $name, string $languageCode): void
- {
- $this->activateLanguageTab($languageCode);
- $this->getElement('name', ['%language%' => $languageCode])->setValue($name);
-
- if (DriverHelper::isJavascript($this->getDriver())) {
- SlugGenerationHelper::waitForSlugGeneration(
- $this->getSession(),
- $this->getElement('slug', ['%language%' => $languageCode]),
- );
- }
- }
-
- public function specifySlug(string $slug, string $languageCode): void
- {
- $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug);
- }
-
- public function attachImage(string $path, ?string $type = null): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $this->getDocument()->find('css', '[data-form-collection="add"]')->click();
-
- $imageForm = $this->getLastImageElement();
- $imageForm->fillField('Type', $type);
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
public function getLeaves(?TaxonInterface $parentTaxon = null): array
{
return $this->getDocument()->findAll('css', '.sylius-tree__item');
@@ -166,7 +137,6 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
'code' => '#sylius_taxon_code',
'confirmation_button' => '#confirmation-button',
'description' => '#sylius_taxon_translations_en_US_description',
- 'images' => '#sylius_taxon_images',
'language_tab' => '[data-locale="%locale%"] .title',
'name' => '#sylius_taxon_translations_%language%_name',
'slug' => '#sylius_taxon_translations_%language%_slug',
@@ -174,14 +144,4 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
'tree_item' => '.sylius-tree__item a:contains("%taxon%")',
]);
}
-
- private function getLastImageElement(): NodeElement
- {
- $images = $this->getElement('images');
- $items = $images->findAll('css', 'div[data-form-collection="item"]');
-
- Assert::notEmpty($items);
-
- return end($items);
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php
index 25d5667ed1..b0ebdb429e 100644
--- a/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php
@@ -30,14 +30,8 @@ interface CreatePageInterface extends BaseCreatePageInterface
public function hasTaxonWithName(string $name): bool;
- public function nameIt(string $name, string $languageCode): void;
-
public function specifyCode(string $code): void;
- public function specifySlug(string $slug, string $languageCode): void;
-
- public function attachImage(string $path, ?string $type = null): void;
-
/**
* @return NodeElement[]
*
diff --git a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php
index 0a5a21cac2..ef9de2cd40 100644
--- a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php
+++ b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php
@@ -41,54 +41,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
$this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_description', $languageCode), $description);
}
- public function nameIt(string $name, string $languageCode): void
- {
- $this->activateLanguageTab($languageCode);
- $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name);
-
- if (DriverHelper::isJavascript($this->getDriver())) {
- SlugGenerationHelper::waitForSlugGeneration(
- $this->getSession(),
- $this->getElement('slug', ['%language%' => $languageCode]),
- );
- }
- }
-
- public function specifySlug(string $slug, string $languageCode): void
- {
- $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug);
- }
-
- public function attachImage(string $path, ?string $type = null): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $this->getDocument()->find('css', '[data-form-collection="add"]')->click();
-
- $imageForm = $this->getLastImageElement();
- if (null !== $type) {
- $imageForm->fillField('Type', $type);
- }
-
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function isImageWithTypeDisplayed(string $type): bool
- {
- $imageElement = $this->getImageElementByType($type);
-
- $imageUrl = $imageElement ? $imageElement->find('css', 'img')->getAttribute('src') : $this->provideImageUrlForType($type);
- if (null === $imageElement && null === $imageUrl) {
- return false;
- }
-
- $this->getDriver()->visit($imageUrl);
- $statusCode = $this->getDriver()->getStatusCode();
- $this->getDriver()->back();
-
- return in_array($statusCode, [200, 304], true);
- }
-
public function isSlugReadonly(string $languageCode = 'en_US'): bool
{
return SlugGenerationHelper::isSlugReadonly(
@@ -97,33 +49,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
);
}
- public function removeImageWithType(string $type): void
- {
- $imageElement = $this->getImageElementByType($type);
- $imageSourceElement = $imageElement->find('css', 'img');
- if (null !== $imageSourceElement) {
- $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src'));
- }
-
- $imageElement->clickLink('Delete');
- }
-
- public function removeFirstImage(): void
- {
- $imageElement = $this->getFirstImageElement();
- $imageTypeElement = $imageElement->find('css', 'input[type=text]');
- $imageSourceElement = $imageElement->find('css', 'img');
-
- if (null !== $imageTypeElement && null !== $imageSourceElement) {
- $this->saveImageUrlForType(
- $imageTypeElement->getValue(),
- $imageSourceElement->getAttribute('src'),
- );
- }
-
- $imageElement->clickLink('Delete');
- }
-
public function enableSlugModification(string $languageCode = 'en_US'): void
{
SlugGenerationHelper::enableSlugModification(
@@ -132,29 +57,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
);
}
- public function countImages(): int
- {
- $imageElements = $this->getImageElements();
-
- return count($imageElements);
- }
-
- public function changeImageWithType(string $type, string $path): void
- {
- $filesPath = $this->getParameter('files_path');
-
- $imageForm = $this->getImageElementByType($type);
- $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
- }
-
- public function modifyFirstImageType(string $type): void
- {
- $firstImage = $this->getFirstImageElement();
-
- $typeField = $firstImage->findField('Type');
- $typeField->setValue($type);
- }
-
public function getParent(): string
{
return $this->getElement('parent')->getValue();
@@ -238,7 +140,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
'code' => '#sylius_taxon_code',
'description' => '#sylius_taxon_translations_en_US_description',
'enabled' => '#sylius_taxon_enabled',
- 'images' => '#sylius_taxon_images',
'language_tab' => '[data-locale="%locale%"] .title',
'name' => '#sylius_taxon_translations_en_US_name',
'parent' => '#sylius_taxon_parent',
@@ -256,15 +157,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return end($imageElements);
}
- private function getFirstImageElement(): NodeElement
- {
- $imageElements = $this->getImageElements();
-
- Assert::notEmpty($imageElements);
-
- return reset($imageElements);
- }
-
/**
* @return NodeElement[]
*/
@@ -274,30 +166,4 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $images->findAll('css', 'div[data-form-collection="item"]');
}
-
- private function getImageElementByType(string $type): ?NodeElement
- {
- $images = $this->getElement('images');
- $typeInput = $images->find('css', 'input[value="' . $type . '"]');
-
- if (null === $typeInput) {
- return null;
- }
-
- return $typeInput->getParent()->getParent()->getParent();
- }
-
- private function provideImageUrlForType(string $type): ?string
- {
- return $this->imageUrls[$type] ?? null;
- }
-
- private function saveImageUrlForType(string $type, string $imageUrl): void
- {
- if (str_contains($imageUrl, 'data:image/jpeg')) {
- return;
- }
-
- $this->imageUrls[$type] = $imageUrl;
- }
}
diff --git a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php
index 9740f748a9..bb65f67be9 100644
--- a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php
+++ b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php
@@ -25,28 +25,10 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function isCodeDisabled(): bool;
- public function nameIt(string $name, string $languageCode): void;
-
- public function specifySlug(string $slug, string $languageCode): void;
-
- public function attachImage(string $path, ?string $type = null): void;
-
- public function isImageWithTypeDisplayed(string $type): bool;
-
public function isSlugReadonly(string $languageCode = 'en_US'): bool;
- public function removeImageWithType(string $type): void;
-
- public function removeFirstImage(): void;
-
public function enableSlugModification(string $languageCode = 'en_US'): void;
- public function countImages(): int;
-
- public function changeImageWithType(string $type, string $path): void;
-
- public function modifyFirstImageType(string $type): void;
-
public function getParent(): string;
public function getSlug(string $languageCode = 'en_US'): string;
diff --git a/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php b/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php
deleted file mode 100644
index ba46579d45..0000000000
--- a/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php
+++ /dev/null
@@ -1,80 +0,0 @@
-getDocument()->clickLink('Add member');
- }
-
- public function checkValidationMessageForMembers(string $message): bool
- {
- $membersValidationElement = $this->getElement('ui_segment')->find('css', '.sylius-validation-error');
- if (null === $membersValidationElement) {
- throw new ElementNotFoundException($this->getDriver(), 'members validation box', 'css', '.sylius-validation-error');
- }
-
- return $membersValidationElement->getText() === $message;
- }
-
- public function chooseMember(string $name): void
- {
- $selectItems = $this->getDocument()->waitFor(2, fn () => $this->getDocument()->findAll('css', 'div[data-form-type="collection"] select'));
- $lastSelectItem = end($selectItems);
-
- if (false === $lastSelectItem) {
- throw new ElementNotFoundException($this->getSession(), 'select', 'css', 'div[data-form-type="collection"] select');
- }
-
- $lastSelectItem->selectOption($name);
- }
-
- public function selectScope(string $scope): void
- {
- $this->getDocument()->selectFieldOption('Scope', $scope);
- }
-
- public function hasType(string $type): bool
- {
- $typeField = $this->getElement('type');
- $selectedOption = $typeField->find('css', 'option[selected]');
-
- return lcfirst($selectedOption->getText()) === $type;
- }
-
- public function isTypeFieldDisabled(): bool
- {
- return $this->getElement('type')->hasAttribute('disabled');
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_zone_code',
- 'name' => '#sylius_zone_name',
- 'type' => '#sylius_zone_type',
- 'ui_segment' => '.ui.segment',
- ]);
- }
-}
diff --git a/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php
deleted file mode 100644
index ba270d76e2..0000000000
--- a/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php
+++ /dev/null
@@ -1,35 +0,0 @@
-getSelectedZoneMembers();
-
- return count($selectedZoneMembers);
- }
-
- public function getScope(): string
- {
- return $this->getElement('scope')->getValue();
- }
-
- public function hasMember(ZoneMemberInterface $zoneMember): bool
- {
- $selectedZoneMembers = $this->getSelectedZoneMembers();
-
- foreach ($selectedZoneMembers as $selectedZoneMember) {
- if ($selectedZoneMember->getValue() === $zoneMember->getCode()) {
- return true;
- }
- }
-
- return false;
- }
-
- public function removeMember(ZoneMemberInterface $zoneMember): void
- {
- $zoneMembers = $this->getElement('zone_members');
- $items = $zoneMembers->findAll('css', 'div[data-form-collection="item"]');
-
- /** @var NodeElement $item */
- foreach ($items as $item) {
- $selectedItem = $item->find('css', 'option[selected="selected"]');
-
- if (null === $selectedItem) {
- throw new ElementNotFoundException($this->getDriver(), 'selected option', 'css', 'option[selected="selected"]');
- }
-
- if ($selectedItem->getValue() === $zoneMember->getCode()) {
- $this->getDeleteButtonForCollectionItem($item)->click();
-
- break;
- }
- }
- }
-
- /**
- * @throws ElementNotFoundException
- */
- protected function getCodeElement(): NodeElement
- {
- return $this->getElement('code');
- }
-
- protected function getDefinedElements(): array
- {
- return array_merge(parent::getDefinedElements(), [
- 'code' => '#sylius_zone_code',
- 'member' => '.one.field',
- 'name' => '#sylius_zone_name',
- 'scope' => '#sylius_zone_scope',
- 'type' => '#sylius_zone_type',
- 'zone_members' => '#sylius_zone_members',
- ]);
- }
-
- /**
- * @throws ElementNotFoundException
- */
- private function getDeleteButtonForCollectionItem(NodeElement $item): NodeElement
- {
- $deleteButton = $item->find('css', 'a[data-form-collection="delete"]');
- if (null === $deleteButton) {
- throw new ElementNotFoundException($this->getDriver(), 'link', 'css', 'a[data-form-collection="delete"]');
- }
-
- return $deleteButton;
- }
-
- /**
- * @return NodeElement[]
- *
- * @throws ElementNotFoundException
- */
- private function getSelectedZoneMembers(): array
- {
- $zoneMembers = $this->getElement('zone_members');
-
- return $zoneMembers->findAll('css', 'option[selected="selected"]');
- }
-}
diff --git a/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php
deleted file mode 100644
index bcc006d9a4..0000000000
--- a/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php
+++ /dev/null
@@ -1,32 +0,0 @@
-
%kernel.project_dir%/var/date.txt
+ [data-test-sylius-flash-message]
+ .sylius-flash-message
+
+ alert-danger
+ alert-info
+ alert-success
+
+
+ negative
+ info
+ positive
+
@@ -86,12 +98,24 @@
-
+
+ %sylius.behat.notification_accessor.admin.locator%
-
-
+
+
+ %sylius.behat.notification_accessor.shop.locator%
+
+
+
+
+ %sylius.behat.notification_checker.admin.class_map%
+
+
+
+
+ %sylius.behat.notification_checker.shop.class_map%
@@ -101,6 +125,8 @@
+
+
10000007
diff --git a/src/Sylius/Behat/Resources/config/services/contexts/ui.xml b/src/Sylius/Behat/Resources/config/services/contexts/ui.xml
index 135272efe4..f5405cc693 100644
--- a/src/Sylius/Behat/Resources/config/services/contexts/ui.xml
+++ b/src/Sylius/Behat/Resources/config/services/contexts/ui.xml
@@ -35,7 +35,7 @@
-
+
@@ -53,7 +53,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
@@ -82,7 +82,7 @@
-
+
@@ -120,7 +120,7 @@
-
+
@@ -129,22 +129,25 @@
-
-
+
+
+
+
+
-
+
-
+
@@ -153,7 +156,6 @@
- OfflinePaypal Express Checkout
@@ -189,7 +191,7 @@
-
+
@@ -199,7 +201,8 @@
-
+
+
@@ -219,7 +222,7 @@
-
+
@@ -233,7 +236,7 @@
-
+
@@ -252,7 +255,7 @@
-
+
@@ -262,15 +265,15 @@
-
+
-
-
+
+
@@ -295,8 +298,10 @@
+
+
-
+
@@ -310,16 +315,15 @@
-
+
-
-
+
+
-
-
+
@@ -327,25 +331,26 @@
+
-
+
-
+
-
+
@@ -410,7 +415,7 @@
-
+
@@ -459,7 +464,7 @@
-
+
@@ -470,7 +475,7 @@
-
+
@@ -486,14 +491,14 @@
-
+
-
+
@@ -518,7 +523,7 @@
-
+
@@ -542,7 +547,7 @@
-
+
@@ -556,7 +561,7 @@
-
+
diff --git a/src/Sylius/Behat/Resources/config/services/elements/admin.xml b/src/Sylius/Behat/Resources/config/services/elements/admin.xml
index 839891a9a6..918274b37d 100644
--- a/src/Sylius/Behat/Resources/config/services/elements/admin.xml
+++ b/src/Sylius/Behat/Resources/config/services/elements/admin.xml
@@ -16,20 +16,32 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
>
+
+
+
+
-
+
+
+
+
+
+ parent="sylius.behat.element.admin.crud.form"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml
index 222aca9d32..a1e1efe886 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml
@@ -23,12 +23,14 @@
sylius_admin_channel_create
+ sylius_admin_channel_indexsylius_admin_channel_update
+
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml
index 92948a9daa..58c5a51ef3 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml
@@ -28,6 +28,7 @@
sylius_admin_customer_index
+ sylius_admin_customer_order_index
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml
index f84437d4d4..6c3507a3d9 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml
@@ -27,7 +27,6 @@
- sylius_admin_order_update
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml
index 74c8cfd354..a638ed1ff5 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml
@@ -27,9 +27,11 @@
sylius_admin_product_create
+ sylius_admin_product_create
+ sylius_admin_product_index
@@ -40,9 +42,11 @@
sylius_admin_product_update
+ sylius_admin_product_update
+
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml
index 7aae42736e..cf8c1a23ed 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml
@@ -13,9 +13,9 @@
- Sylius\Behat\Page\Admin\ProductAssociationType\CreatePage
+ %sylius.behat.page.admin.crud.create.class%Sylius\Behat\Page\Admin\ProductAssociationType\IndexPage
- Sylius\Behat\Page\Admin\ProductAssociationType\UpdatePage
+ %sylius.behat.page.admin.crud.update.class%
diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml
index 2319e8aafd..8eac969c03 100644
--- a/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml
+++ b/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml
@@ -13,9 +13,9 @@
- Sylius\Behat\Page\Admin\Zone\CreatePage
+ %sylius.behat.page.admin.crud.create.class%%sylius.behat.page.admin.crud.index.class%
- Sylius\Behat\Page\Admin\Zone\UpdatePage
+ %sylius.behat.page.admin.crud.update.class%
diff --git a/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml b/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml
index cd5d323ab3..8cdfaa3fb3 100644
--- a/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml
+++ b/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml
@@ -3,7 +3,7 @@
default:
suites:
- ui_managing_inventory:
+ ui_inventory_on_product_page:
contexts:
- sylius.behat.context.hook.doctrine_orm
- sylius.behat.context.hook.session
diff --git a/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml b/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml
index 6541042c0f..55313fef7e 100644
--- a/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml
+++ b/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml
@@ -35,6 +35,7 @@ default:
- sylius.behat.context.transform.order
- sylius.behat.context.transform.payment
- sylius.behat.context.transform.product
+ - sylius.behat.context.transform.province
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.transform.tax_category
- sylius.behat.context.transform.tax_rate
diff --git a/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml b/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml
index 21f3ebd5ec..28068928d3 100644
--- a/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml
+++ b/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml
@@ -25,10 +25,10 @@ default:
- sylius.behat.context.transform.product
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.transform.zone
-
- sylius.behat.context.transform.shared_storage
- sylius.behat.context.ui.admin.managing_orders
+ - sylius.behat.context.ui.admin.order_history
filters:
tags: "@order_history&&@ui"
diff --git a/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml b/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml
index 8bec36025b..8a91b83d12 100644
--- a/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml
+++ b/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml
@@ -18,6 +18,7 @@ default:
- sylius.behat.context.transform.product
- sylius.behat.context.transform.shared_storage
- sylius.behat.context.transform.shipping_method
+ - sylius.behat.context.transform.zone
- sylius.behat.context.setup.channel
- sylius.behat.context.setup.currency
diff --git a/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml b/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml
index 7494a1b012..76e9655706 100644
--- a/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml
+++ b/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml
@@ -10,6 +10,7 @@ default:
- sylius.behat.context.hook.session
- sylius.behat.context.transform.address
+ - sylius.behat.context.transform.channel
- sylius.behat.context.transform.customer
- sylius.behat.context.transform.customer_group
- sylius.behat.context.transform.payment
diff --git a/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php b/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php
index 6cfe928930..88baa54f47 100644
--- a/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php
+++ b/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php
@@ -16,18 +16,20 @@ namespace Sylius\Behat\Service\Accessor;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Session;
-final class NotificationAccessor implements NotificationAccessorInterface
+final readonly class NotificationAccessor implements NotificationAccessorInterface
{
- public function __construct(private Session $session)
- {
+ public function __construct(
+ private Session $session,
+ private string $locator,
+ ) {
}
public function getMessageElements(): array
{
- $messageElements = $this->session->getPage()->findAll('css', '.sylius-flash-message');
+ $messageElements = $this->session->getPage()->findAll('css', $this->locator);
if (empty($messageElements)) {
- throw new ElementNotFoundException($this->session->getDriver(), 'message element', 'css', '.sylius-flash-message');
+ throw new ElementNotFoundException($this->session->getDriver(), 'message element', 'css', $this->locator);
}
return $messageElements;
diff --git a/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php b/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php
new file mode 100644
index 0000000000..60cddbaa03
--- /dev/null
+++ b/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php
@@ -0,0 +1,149 @@
+normalizeSelector($selector);
+ $result = $driver->evaluateScript(<<
-
-
- {% endblock %}
-
-
-
-