@webship-js/prestashop-steps 0.0.0-stage → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Webship.co
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,298 @@
1
- # Temporary Holding Version
1
+ # @webship-js/prestashop-steps
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Cucumber step definitions for testing PrestaShop shops with [webship-js](https://github.com/webship/webship-js)
4
+ (Playwright and Cucumber): the back office and the shop, in plain sentences.
5
+
6
+ ```gherkin
7
+ Scenario: A customer pays by check and the employee accepts the payment
8
+ Given I am signed in to the shop as "customer"
9
+ And I am on "/index.php?id_product=7&controller=product"
10
+ When I add the product to the cart
11
+ And I proceed to checkout from the cart dialog
12
+ And I proceed to checkout
13
+ And I continue the checkout
14
+ And I continue the checkout
15
+ And I choose the payment method "Pay by Check"
16
+ And I accept the terms of service
17
+ And I place the order
18
+ Then the order should be confirmed
19
+ Given I am logged in to the back office as "admin"
20
+ When I open the placed order in the back office
21
+ And I change the order status to "Payment accepted"
22
+ Then I should see the success message "Successful update"
23
+ And my order history should list the placed order as "Payment accepted"
24
+ ```
25
+
26
+ Every step was written from the real pages of a real install (PrestaShop 9.2.1, default theme) opened in a browser, and
27
+ the whole suite of this repository runs against such an install on every push, twice in a row.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ npm install --save-dev webship-js @webship-js/prestashop-steps
33
+ npx playwright install chromium
34
+ ```
35
+
36
+ Load the steps after the webship-js ones in your `cucumber.js`:
37
+
38
+ ```js
39
+ require: [
40
+ 'node_modules/webship-js/tests/step-definitions/**/*.js',
41
+ 'node_modules/@webship-js/prestashop-steps/tests/step-definitions/**/*.js',
42
+ 'tests/step-definitions/**/*.js',
43
+ ],
44
+ ```
45
+
46
+ and tell the steps where the shop is and which accounts they may use (`worldParameters`):
47
+
48
+ ```js
49
+ worldParameters: {
50
+ launchUrl: process.env.LAUNCH_URL || 'https://my-shop.ddev.site',
51
+ // The back office lives in a folder with a random name on a default install.
52
+ backOffice: { folder: process.env.ADMIN_FOLDER || 'admin-steps' },
53
+ employees: {
54
+ admin: { email: 'admin@example.com', password: process.env.SHOP_ADMIN_PASSWORD, name: 'Shop Admin' },
55
+ salesman: { email: 'salesman@example.com', password: process.env.SHOP_SALESMAN_PASSWORD, name: 'Sam Salesman' },
56
+ },
57
+ customers: {
58
+ customer: { email: 'customer@example.com', password: process.env.SHOP_CUSTOMER_PASSWORD, name: 'Clara Customer' },
59
+ },
60
+ }
61
+ ```
62
+
63
+ The complete `cucumber.js` of this repository is a working example.
64
+
65
+ ### Accounts are configuration
66
+
67
+ `I am logged in to the back office as "admin"` and `I am signed in to the shop as "customer"` take a handle of those
68
+ registries. The accounts are created once when the test shop is built
69
+ ([`.github/scripts/provision-accounts.php`](.github/scripts/provision-accounts.php) creates the employee and the customers
70
+ without the browser); no step creates or deletes an employee. Never point the suite at a shop with real customers: it
71
+ places orders.
72
+
73
+ ## What you need to know about the platform
74
+
75
+ These are the things the steps handle for you, found while exploring a real shop:
76
+
77
+ - **The security token.** A back-office address without `_token` does not open: it shows the "Invalid token" page. The
78
+ steps follow the links of the main menu (`I open "Catalog > Products" in the back office menu`) or add the token of the
79
+ session (`I open the back office path "improve/modules/manage"`).
80
+ - **Two page generations.** New pages (`/sell/…`, `/improve/…`) and legacy pages (`index.php?controller=Admin…`, such as
81
+ Discounts and Customer Service) render the header, the lists, the dialogs and the messages differently. The same steps
82
+ work on both.
83
+ - **Three kinds of confirmation dialogs.** `I confirm the dialog` and `I cancel the dialog` answer whichever is open.
84
+ - **Messages differ by one word.** "Successful update" after a status change, "Update successful" after a note. Copy the
85
+ text from the page.
86
+ - **The product page.** "Add new product" opens a frame inside a dialog and creates the product at once; "Save" stays
87
+ disabled until a field was changed and left; the stock is changed by a difference, not set.
88
+ - **The shop tells who is signed in and what the cart holds** through its `prestashop` object. The session, page kind
89
+ and cart count steps read it; the other shop steps use roles, labels and the hooks of the default theme (Hummingbird).
90
+
91
+ ## Steps
92
+
93
+ <!-- steps:start -->
94
+ 141 steps in three files. The sentence shown is the first of the five examples of each step; "I" may be "we".
95
+
96
+ ### The back office: session, menu, lists, dialogs, forms — `prestashop-back-office.steps.js` (45 steps)
97
+
98
+ | Step (first example) | What it does |
99
+ |---|---|
100
+ | `Given I am logged in to the back office as "admin"` | Log in to the back office as an employee of the registry (`worldParameters.employees` in cucumber.js), by its handle. |
101
+ | `When I log in to the back office with "admin@example.com" and "wrong-password"` | Send the sign-in form of the back office with an e-mail address and a password, without expecting it to succeed. |
102
+ | `When I log out of the back office` | Log out of the back office through the employee menu of the header, the way a person does. |
103
+ | `Then I should be logged in to the back office` | Assert that an employee session is open (the header shows the employee menu with "Sign out") or that it is not (the sign-in form is shown instead). |
104
+ | `Then the back office should greet "Shop"` | Assert the first name the employee menu greets ("Welcome back Shop"). |
105
+ | `When I open "Catalog > Products" in the back office menu` | Open a page from the main menu of the back office, by the labels a person reads. |
106
+ | `Then I should see "Modules" in the back office menu` | Assert that the main menu shows, or does not show, an entry or an item to the employee. |
107
+ | `Then the current back office menu item should be "Products"` | Assert which item of the main menu is the current one, by its label. |
108
+ | `Then the back office page title should be "Products"` | Assert the title of the back-office page (its h1). |
109
+ | `Then the back office breadcrumb should be "Catalog > Products"` | Assert the breadcrumb of the back-office page, written with " > " between its parts. |
110
+ | `When I press the back office toolbar button "Add new category"` | Press a button of the toolbar at the top right of a back-office page, by its label. |
111
+ | `When I open the back office path "improve/modules/manage"` | Open a back-office address by its path after the back-office folder, with the security token of the session (read from the menu links). |
112
+ | `When I open the back office path "sell/catalog/products/" without the security token` | Open a back-office address without the security token, as a pasted or bookmarked link would. |
113
+ | `Then I should see the invalid security token page` | Assert that the back office shows its "Invalid token" page, which asks whether to display a page opened without the security token. |
114
+ | `Then I should see the access denied page` | Assert that the back office refused the page to the employee. |
115
+ | `Then I should see the success message "Successful update"` | Assert a message of the page by its type and text. |
116
+ | `Then I should not see any error message` | Assert that the page shows no message of a type at all, for example no error after saving. |
117
+ | `Then I should see the notification "The status has been successfully updated."` | Assert the notification that slides in at the top right of the back office after an action that does not reload the page (a row switch, a module). |
118
+ | `Then I should see the field error "The field name is required at least in your default language."` | Assert the error a form shows under one of its fields, in the back office (a red line under the field) or in the shop. |
119
+ | `Then I should see the confirmation dialog "Duplicate product"` | Assert that a confirmation dialog is open and that its title or its text contains the given words. |
120
+ | `When I confirm the dialog` | Confirm the open dialog. |
121
+ | `When I cancel the dialog` | Cancel the open dialog. |
122
+ | `Then I should not see a confirmation dialog` | Assert that no confirmation dialog is open (any more). |
123
+ | `When I filter the list by "Name" with "mug"` | Filter the list of the page by one of its columns. |
124
+ | `When I reset the list filters` | Reset the filters of the list ("Reset"), so it shows every record again. |
125
+ | `Then the list should have 5 rows` | Assert how many records the list shows on this page. |
126
+ | `Then I should see "Customizable mug" in the list` | Assert that the list shows, or does not show, a row containing the text. |
127
+ | `Then the first row of the list should contain "Customizable mug"` | Assert that the first row of the list contains the text. |
128
+ | `Then the "Quantity" of the list row "Customizable mug" should be "300"` | Assert the content of one cell. |
129
+ | `When I open the list row "Customizable mug"` | Open a record from the list by the main action of its row. |
130
+ | `When I choose "Duplicate" for the list row "Customizable mug"` | Choose an action of a list row by its name. |
131
+ | `When I select the list row "Webship bulk mug"` | Tick the checkbox of a list row, to act on it with a bulk action. |
132
+ | `When I choose the bulk action "Delete selection"` | Choose a bulk action for the selected rows from the "Bulk actions" menu, which is disabled until a row is selected. |
133
+ | `When I wait for the bulk action to finish` | Wait for a bulk action of the products list to finish. |
134
+ | `When I flip the "Status" switch of the list row "Webship bulk mug"` | Flip the switch a list row shows in a column (the "Status" of a product, the "Displayed" of a category, the "Enabled" of a customer). |
135
+ | `Then the "Status" switch of the list row "Webship bulk mug" should be on` | Assert whether the switch a list row shows in a column is on or off. |
136
+ | `When I sort the list by "Name" in ascending order` | Sort the list by a column, in ascending or descending order, with the sort control of its title. |
137
+ | `When I show 10 rows per page in the list` | Choose how many records the list shows per page ("Items per page"). |
138
+ | `When I go to the next page of the list` | Go to the next or to the previous page of the list. |
139
+ | `Then the list pagination should read "Viewing 1-10 out of 19 (page 1 / 2)"` | Assert what the pagination of the list reads, for example "Viewing 1-10 out of 19 (page 1 / 2)". |
140
+ | `When I fill in the back office field "Name" with "Webship test category"` | Fill in a field of a back-office form, found by the label a person reads next to it. |
141
+ | `Then the back office field "Name" should contain "Webship test category"` | Assert the value of a field of a back-office form, found by its label. |
142
+ | `When I choose "Percent (%)" for the back office field "Apply a discount"` | Choose an option of a back-office field made of radio buttons or of a select, found by the label of the field and the label of the option. |
143
+ | `When I open the back office form tab "Actions"` | Open a tab of a back-office form by its title (the tabs of the product page, or "Information", "Conditions", "Actions" of a cart rule). |
144
+ | `When I save the back office form` | Save the back-office form of the page with its "Save" button and wait for the answer of the back office. |
145
+
146
+ ### The back office: products, orders, modules, clean-up — `prestashop-catalog.steps.js` (32 steps)
147
+
148
+ | Step (first example) | What it does |
149
+ |---|---|
150
+ | `When I create a "standard" product` | Create a product of a type from the products list. |
151
+ | `When I set the product name to "Webship test mug"` | Set the name of the product on the product page. |
152
+ | `Then the product name should be "Webship test mug"` | Assert the name the product page shows. |
153
+ | `When I set the product price to "21.50"` | Set the retail price of the product, tax excluded (Pricing tab). |
154
+ | `Then the product price should be "21.50"` | Assert the retail price of the product, tax excluded, as a number. |
155
+ | `When I add 5 items to the product stock` | Add items to, or remove items from, the stock of the product (Stocks tab). |
156
+ | `Then the product stock should be 305` | Assert the quantity in stock the product page shows (Stocks tab, "Edit quantity"), as saved. |
157
+ | `When I set the product reference to "webship_1"` | Set the reference of the product (Details tab). |
158
+ | `When I add the product to the category "Men"` | Add the product to a category. |
159
+ | `Then the product should be in the category "Men"` | Assert that the product page lists, or does not list, a category among the categories of the product (Description tab). |
160
+ | `When I upload the product image "product.png"` | Upload an image of the product from the fixtures folder of the suite (`tests/fixtures`), on the Description tab. |
161
+ | `Then the product should have 1 image` | Assert how many images the product has (Description tab). |
162
+ | `When I put the product online` | Put the product online (visible in the shop) or offline, with the switch at the top of the product page. |
163
+ | `Then the product should be online` | Assert whether the product page shows the product as online or offline. |
164
+ | `When I save the product` | Save the product ("Save") and wait for the product page to load again with the answer of the back office. |
165
+ | `When I delete the product from its page` | Start deleting the product from its page (the menu next to "Go to catalog", "Delete"). |
166
+ | `When I go back to the catalog` | Leave the product page for the products list ("Go to catalog"). |
167
+ | `Given no "Webship test mug" is left in "Catalog > Products"` | Delete every record of a list of the back office whose row shows the given text, and confirm each dialog. |
168
+ | `When I open the placed order in the back office` | Open the page of the order that was placed in the shop earlier in the scenario (the step "I place the order" remembers its reference), from the orders list of the back office. |
169
+ | `Then I should see the placed order in the list` | Assert that the list of the page (the orders list) shows the order that was placed in the shop earlier in the scenario, by its reference. |
170
+ | `Then the order page should be titled "KHWLILZLL from John DOE"` | Assert the title of the order page. |
171
+ | `When I change the order status to "Payment accepted"` | Change the status of the order on its page. |
172
+ | `Then the order status should be "Payment accepted"` | Assert the current status of the order, as its page shows it. |
173
+ | `Then the latest order history entry should be "Payment accepted"` | Assert the newest line of the status history of the order. |
174
+ | `Then the order history should have 2 entries` | Assert how many lines the status history of the order has. |
175
+ | `When I set the order note to "Call the customer before shipping"` | Write the private note of the order ("Order private note") and save it. |
176
+ | `Then the order note should be "Call the customer before shipping"` | Assert the private note of the order. |
177
+ | `Then the order should contain the product "Mug The best is yet to come"` | Assert that the order page lists a product among the products of the order. |
178
+ | `When I search the modules for "Banner"` | Search the Module manager for a word. |
179
+ | `Then I should see the module "Banner"` | Assert that the Module manager shows, or does not show, the card of a module (after a search, only the matching cards are shown). |
180
+ | `When I disable the module "Banner"` | Enable or disable an installed module in the Module manager, confirm the dialog a disable asks for, and wait until the card shows the new state. |
181
+ | `Then the module "Banner" should be enabled` | Assert whether an installed module is enabled or disabled, as its card in the Module manager says. |
182
+
183
+ ### The shop — `prestashop.steps.js` (64 steps)
184
+
185
+ | Step (first example) | What it does |
186
+ |---|---|
187
+ | `Given I am signed in to the shop as "customer"` | Sign in to the shop as a customer of the registry (`worldParameters.customers` in cucumber.js), by its handle. |
188
+ | `When I sign in to the shop with "customer@example.com" and "wrong-password"` | Send the sign-in form of the shop with an e-mail address and a password, without expecting it to succeed. |
189
+ | `When I sign out of the shop` | Sign out of the shop through the customer menu of the header ("Sign out"). |
190
+ | `Then I should be signed in to the shop` | Assert that a customer is signed in to the shop, optionally by the name the header shows, or that nobody is. |
191
+ | `Given I am on the shop "cart" page` | Open a page of the shop by its kind. |
192
+ | `Then I should be on a "category" shop page` | Assert the kind of shop page that is shown, as the shop names it (the id of the body). |
193
+ | `When I open "Clothes" in the shop menu` | Open a category from the main menu of the shop. |
194
+ | `Then the shop breadcrumb should be "Home > Accessories"` | Assert the breadcrumb of the shop page, written with " > " between its parts. |
195
+ | `Then the product list should show 11 products` | Assert how many products the product list shows on this page. |
196
+ | `Then the product list should announce "There are 11 products."` | Assert the sentence above the product list that counts the products found, for example "There are 11 products." The text may be a part of it. |
197
+ | `Then I should see the product "Customizable mug" in the product list` | Assert that the product list shows, or does not show, a product by its name. |
198
+ | `Then the first product of the product list should be "Brown bear cushion"` | Assert the product at a position of the product list (first, second, third… or last), to check a sort order. |
199
+ | `When I sort the product list by "Name, A to Z"` | Sort the product list by one of the orders of its "Sort by" menu. |
200
+ | `Then the product list should be sorted by "Name, A to Z"` | Assert the sort order the product list says it uses. |
201
+ | `When I filter the product list by "Categories" with "Stationery"` | Filter the product list with one option of a filter of the "Filter By" block (the filter is opened first, when it is folded). |
202
+ | `Then the active filters should include "Categories: Stationery"` | Assert that the product list shows, or does not show, an active filter ("Categories. |
203
+ | `When I remove the active filter "Categories: Stationery"` | Remove an active filter of the product list by pressing its chip. |
204
+ | `When I go to the next page of the product list` | Go to the next page, the previous page or a numbered page of the product list. |
205
+ | `Then the product list should be on page 2` | Assert the page of the product list that is shown, by its number. |
206
+ | `When I search the shop for "mug"` | Search the shop. |
207
+ | `When I type "mug" in the shop search` | Type words in the search box of the header without sending them, to see the suggestions the shop offers while typing. |
208
+ | `Then the search suggestions should include "Customizable mug"` | Assert that the suggestions under the search box include, or do not include, a product. |
209
+ | `When I open the product "Hummingbird printed t-shirt"` | Open the page of a product by pressing its name on a product card of the current page (the home page, a category, the search results). |
210
+ | `When I choose "M" for the product option "Size"` | Choose a value for an option of the product (a combination). |
211
+ | `Then the product option "Size" should be "M"` | Assert the value the product page shows as chosen for an option. |
212
+ | `When I set the quantity to buy to 2` | Set the quantity to buy on the product page. |
213
+ | `Then the price of the product should be "$19.12"` | Assert the price the product page shows for the product (the current price, after a discount), as the page writes it. |
214
+ | `When I add the product to the cart` | Add the product of the product page to the cart ("Add to cart") and wait for the dialog that confirms it. |
215
+ | `Then the cart dialog should show "Hummingbird printed t-shirt"` | Assert that the dialog shown after "Add to cart" contains a text. |
216
+ | `When I continue shopping from the cart dialog` | Leave the cart dialog. |
217
+ | `Given my cart is empty` | Empty the cart of the visitor. |
218
+ | `Then the cart should contain "Hummingbird printed t-shirt"` | Assert that the cart page lists, or does not list, a product. |
219
+ | `Then the cart should hold 2 items` | Assert how many items the cart holds (the sum of the quantities), as the shop itself counts them. |
220
+ | `When I change the cart quantity of "Hummingbird printed t-shirt" to 3` | Change the quantity of a line of the cart page. |
221
+ | `Then the cart quantity of "Hummingbird printed t-shirt" should be 3` | Assert the quantity of a line of the cart page. |
222
+ | `When I remove "Hummingbird printed t-shirt" from the cart` | Remove a product from the cart page with the "Remove" link of its line. |
223
+ | `Then the cart should be empty` | Assert that the cart page says the cart is empty. |
224
+ | `When I apply the voucher "WEBSHIP10"` | Apply a voucher (a cart rule code) on the cart page. |
225
+ | `Then the cart should have the voucher "Webship ten percent"` | Assert that the cart lists, or does not list, an applied voucher by the name of its cart rule. |
226
+ | `When I remove the voucher "Webship ten percent"` | Remove an applied voucher from the cart. |
227
+ | `Then the cart summary should show "Total (tax incl.)" as "$45.24"` | Assert a line of the cart summary. |
228
+ | `When I proceed to checkout` | Go on from the cart page to the checkout ("Proceed to checkout"). |
229
+ | `Then the checkout step should be "Personal Information"` | Assert which step of the checkout is open. |
230
+ | `When I fill in the checkout field "First name" with "Greta"` | Fill in a text field of the open checkout step, by its label ("First name", "Email", "Address", "City", "Zip/Postal Code"…). |
231
+ | `When I select "Florida" for the checkout field "State"` | Choose an option of a list field of the open checkout step, by its label ("State", "Country"). |
232
+ | `When I tick the checkout box "Customer data privacy"` | Tick a consent or an option of the open checkout step, by the start of its label ("Customer data privacy", "I agree to the terms and conditions and the privacy policy", "Sign up for our newsletter"). |
233
+ | `When I choose the delivery address "Home"` | Choose one of the saved addresses of the customer as the delivery address, by its alias, on the Addresses step. |
234
+ | `When I choose the delivery option "My carrier"` | Choose a delivery option (a carrier) by its name on the Shipping Method step. |
235
+ | `When I continue the checkout` | Confirm the open checkout step and go to the next one (its "Continue" button), then wait for the next step to open. |
236
+ | `When I choose the payment method "Pay by bank wire"` | Choose a payment method on the Payment step, by the label of its option ("Pay by bank wire", "Pay by Check", "Pay by Cash on Delivery"). |
237
+ | `When I accept the terms of service` | Accept the terms of service on the Payment step (the box "I agree to the terms of service…"). |
238
+ | `Then the place order button should be disabled` | Assert whether the "Place Order" button of the Payment step can be pressed. |
239
+ | `When I place the order` | Place the order ("Place Order") and wait for the order confirmation page. |
240
+ | `Then the order should be confirmed` | Assert that the order confirmation page is shown ("Your order is confirmed"). |
241
+ | `Then the order confirmation should show "Payment method: Bank transfer"` | Assert a detail of the order confirmation page, as it is written under "Order details" ("Payment method. |
242
+ | `Then my order history should list the placed order` | Assert that the order history of the customer lists the order placed earlier in the scenario, optionally with a status. |
243
+ | `When I open the placed order in my order history` | Open the details of the order placed earlier in the scenario from the order history of the customer. |
244
+ | `Then I should see the address "Home"` | Assert that the address book of the customer shows, or does not show, an address by its alias. |
245
+ | `Given I have no address "Office"` | Make sure the address book of the signed-in customer holds no address with the given alias. |
246
+ | `When I delete the address "Office"` | Edit or delete an address of the address book of the customer, by its alias. |
247
+ | `When I fill in the shop field "Alias" with "Office"` | Fill in a field of the form of the page in the shop, by its label, inside the main content. |
248
+ | `When I select "Florida" for the shop field "State"` | Choose an option of a list field of the form of the page in the shop, by its label ("State", "Country", "Subject"). |
249
+ | `When I tick the shop box "Customer data privacy"` | Tick a box of the form of the page in the shop, by the start of its label (the consents of the registration form). |
250
+ | `When I send the shop form` | Send the form of the page in the shop with its own button ("Save" of an address, "Create account" of the registration, "Send your message" of the contact page) and wait for the answer. |
251
+ <!-- steps:end -->
252
+
253
+ Each step has a JSDoc block with five example phrasings in its file under
254
+ [`tests/step-definitions`](tests/step-definitions).
255
+
256
+ ## Clean-up
257
+
258
+ What a scenario creates, it removes. One step does it for the lists of the back office, at the start (an earlier run may
259
+ have stopped half-way) and at the end:
260
+
261
+ ```gherkin
262
+ Given no "Webship test mug" is left in "Catalog > Products"
263
+ And no "newcomer@example.com" is left in "Customers > Customers"
264
+ ```
265
+
266
+ Orders are the exception of the platform: an order cannot be deleted. The scenarios that place one cancel it (the stock
267
+ comes back) and remove the guest customer. `Given my cart is empty` and `Given I have no address "Office"` do the same
268
+ for the cart and the address book of a customer.
269
+
270
+ ## Run the suite of this repository
271
+
272
+ ```bash
273
+ npm ci
274
+ npx playwright install chromium
275
+ # Builds a shop with the demo catalog and the accounts in a DDEV project (project "prestashop-ci").
276
+ .github/scripts/build-ddev-prestashop.sh
277
+ npm run test:examples # every example and feature step against the step patterns
278
+ npx cucumber-js --dry-run # no undefined, no ambiguous step
279
+ npx cucumber-js # the suite
280
+ ```
281
+
282
+ The build script installs the release from the command line, only with the modules of the open source release: no
283
+ marketplace, account, hosted checkout, marketing or AI module is installed, and the shop sends no e-mail.
284
+ `SHOP_VERSION`, `PHP_VERSION`, `PROJECT_NAME`, `SITE_DIR` and `ADMIN_FOLDER` change the build; `LAUNCH_URL` and
285
+ `ADMIN_FOLDER` point the suite at another shop.
286
+
287
+ ## Tested on
288
+
289
+ - PrestaShop 9.2.1 (PHP 8.3, MariaDB 10.11), the default theme (Hummingbird 2.1), English, one shop, default currency and
290
+ country of the installer (United States).
291
+
292
+ Not covered: the Classic theme and themes built on it (the back-office steps do not depend on the theme, the shop steps
293
+ were only run on Hummingbird), other languages of the back office (the menu, the buttons and the messages are matched by their English
294
+ text), multistore, the one-page checkout, online payment modules, returns and credit slips, the import, the web service.
295
+
296
+ ## License
297
+
298
+ MIT
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
2
  "name": "@webship-js/prestashop-steps",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "2.0.1",
4
+ "description": "Cucumber step definitions for testing PrestaShop shops with webship-js: the back office (session, menu, lists, products, categories, orders, customers, discounts, modules, permissions) and the shop (catalog, search, product page, cart, checkout, customer account, contact).",
5
+ "main": "tests/step-definitions/prestashop.steps.js",
6
+ "files": [
7
+ "tests/step-definitions/*.js",
8
+ "tests/step-definitions/README.md",
9
+ "tests/features",
10
+ "tests/fixtures",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "test": "cucumber-js --config cucumber.js",
16
+ "test:dry": "cucumber-js --config cucumber.js --dry-run",
17
+ "test:chromium": "BROWSER=chromium cucumber-js --config cucumber.js",
18
+ "test:firefox": "BROWSER=firefox cucumber-js --config cucumber.js",
19
+ "test:webkit": "BROWSER=webkit cucumber-js --config cucumber.js",
20
+ "test:headed": "HEADLESS=false cucumber-js --config cucumber.js",
21
+ "test:examples": "node tests/check-examples.js",
22
+ "generate-reports": "generate-reports"
23
+ },
24
+ "keywords": [
25
+ "prestashop",
26
+ "e-commerce",
27
+ "webship-js",
28
+ "cucumber",
29
+ "cucumber-js",
30
+ "playwright",
31
+ "bdd",
32
+ "testing",
33
+ "e2e",
34
+ "gherkin"
35
+ ],
36
+ "author": "Webship.co",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/webship/prestashop-steps.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/webship/prestashop-steps/issues"
44
+ },
45
+ "homepage": "https://github.com/webship/prestashop-steps#readme",
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "engines": {
50
+ "node": ">= 20.0"
51
+ },
52
+ "peerDependencies": {
53
+ "webship-js": "^2.0.10"
54
+ },
55
+ "devDependencies": {
56
+ "tsx": "^4.23.0",
57
+ "webship-js": "^2.0.10"
58
+ },
59
+ "overrides": {
60
+ "@cucumber/cucumber": "^12"
61
+ },
62
+ "dependencies": {
63
+ "webship-js": "~2.0.0"
64
+ }
65
+ }
@@ -0,0 +1,25 @@
1
+ # Features
2
+
3
+ The suite of this pack. It runs against a shop built by `.github/scripts/build-ddev-prestashop.sh` (the demo catalog, the
4
+ accounts of `cucumber.js`) and leaves it as it found it: what a scenario creates, it removes. Orders are the exception the
5
+ platform imposes: an order cannot be deleted, so the scenarios that place one cancel it (the stock comes back) and remove
6
+ the guest customer.
7
+
8
+ | Feature | Area |
9
+ |---|---|
10
+ | `back-office-session` | employee sign in and out, the security token |
11
+ | `back-office-navigation` | main menu, title, breadcrumb on new and legacy pages |
12
+ | `back-office-permissions` | what the Salesman profile sees and what is refused |
13
+ | `products-list`, `products-bulk` | filters, sorting, pagination, row switch, bulk actions |
14
+ | `product-create` | create, edit, stock, category, image, duplicate, delete |
15
+ | `categories` | create, validation, rename, hide, delete |
16
+ | `orders` | list, filters, order page, history, private note |
17
+ | `customers` | customers, addresses, shopping carts |
18
+ | `modules` | search, disable, enable |
19
+ | `discounts` | a cart rule from the back office to the cart |
20
+ | `shop-catalog`, `shop-search` | categories, sort, filters, pagination, search, suggestions, 404 |
21
+ | `shop-product-cart` | combinations, quantity, the cart dialog, the cart |
22
+ | `checkout-guest`, `checkout-customer` | the checkout with bank wire, check and cash on delivery, and the order in the back office |
23
+ | `shop-account`, `shop-registration`, `shop-contact` | sign in, addresses, registration, contact form |
24
+
25
+ `@critical` marks the smoke lane: `CUCUMBER_TAGS=@critical npx cucumber-js`.
@@ -0,0 +1,40 @@
1
+ @back-office @navigation
2
+ Feature: The main menu, the title and the breadcrumb of the back office
3
+ As an employee of the shop
4
+ I want to reach every screen from the main menu
5
+ So that I always know where I am
6
+
7
+ Background:
8
+ Given I am logged in to the back office as "admin"
9
+
10
+ @critical
11
+ Scenario: A new page opened from the menu
12
+ When I open "Catalog > Products" in the back office menu
13
+ Then the back office page title should be "Products"
14
+ And the back office breadcrumb should be "Catalog > Products"
15
+ And the current back office menu item should be "Products"
16
+
17
+ Scenario: A legacy page opened from the menu
18
+ When I open "Catalog > Discounts" in the back office menu
19
+ Then the back office page title should be "Cart Rules"
20
+ And the back office breadcrumb should be "Discounts > Cart Rules"
21
+
22
+ Scenario Outline: The lists of the Sell section
23
+ When I open "<menu>" in the back office menu
24
+ Then the back office page title should be "<title>"
25
+ And the back office breadcrumb should be "<breadcrumb>"
26
+
27
+ Examples:
28
+ | menu | title | breadcrumb |
29
+ | Orders > Orders | Orders | Orders |
30
+ | Orders > Shopping Carts | Shopping Carts | Orders > Shopping Carts |
31
+ | Customers > Customers | Customers | Customers |
32
+ | Customers > Addresses | Addresses | Customers > Addresses |
33
+ | Modules > Module Manager | Module manager | Module Manager > Modules |
34
+
35
+ Scenario: The menu shows the three sections to the administrator
36
+ Then I should see "Orders > Orders" in the back office menu
37
+ And I should see "Catalog > Discounts" in the back office menu
38
+ And I should see "Modules > Module Manager" in the back office menu
39
+ And I should see "Advanced Parameters > Team" in the back office menu
40
+ But I should not see "Catalog > Vouchers" in the back office menu
@@ -0,0 +1,39 @@
1
+ @back-office @permissions
2
+ Feature: What a limited employee can and cannot open
3
+ As the owner of the shop
4
+ I want an employee with the Salesman profile to see orders and the catalog only
5
+ So that modules, the team and the dashboard stay with the administrator
6
+
7
+ Background:
8
+ Given I am logged in to the back office as "salesman"
9
+
10
+ @critical
11
+ Scenario: The menu only lists what the profile may open
12
+ Then I should see "Orders > Orders" in the back office menu
13
+ And I should see "Catalog > Products" in the back office menu
14
+ But I should not see "Modules" in the back office menu
15
+ And I should not see "Dashboard" in the back office menu
16
+ And I should not see "Customers > Customers" in the back office menu
17
+ And I should not see "Advanced Parameters > Team" in the back office menu
18
+
19
+ Scenario Outline: A page of the administrator is refused
20
+ When I open the back office path "<path>"
21
+ Then I should see the access denied page
22
+ And I should see "Back to previous page"
23
+
24
+ Examples:
25
+ | path |
26
+ | improve/modules/manage |
27
+ | configure/advanced/employees/ |
28
+ | index.php?controller=AdminDashboard |
29
+
30
+ Scenario: A page of the profile opens
31
+ When I open "Catalog > Products" in the back office menu
32
+ Then I should not see the access denied page
33
+ And the back office page title should be "Products"
34
+ And I should see "Customizable mug" in the list
35
+
36
+ Scenario: The orders are open to the profile
37
+ When I open "Orders > Orders" in the back office menu
38
+ Then I should not see the access denied page
39
+ And I should see "XKBKNABJK" in the list
@@ -0,0 +1,51 @@
1
+ @back-office @session
2
+ Feature: The employee session of the back office
3
+ As an employee of the shop
4
+ I want to log in to and out of the back office
5
+ So that only employees manage the shop
6
+
7
+ @critical
8
+ Scenario: The administrator logs in and lands on the dashboard
9
+ Given I am logged in to the back office as "admin"
10
+ Then I should be logged in to the back office
11
+ And the back office should greet "Shop"
12
+ And the back office page title should be "Dashboard"
13
+ And the current back office menu item should be "Dashboard"
14
+
15
+ Scenario: A wrong password is refused with a message
16
+ When I log in to the back office with "admin@example.com" and "wrong-password"
17
+ Then I should not be logged in to the back office
18
+ And I should see the error message "The employee does not exist, or the password provided is incorrect."
19
+
20
+ Scenario: An unknown employee is refused with the same message
21
+ When I log in to the back office with "nobody@example.com" and "Whatever123456789!"
22
+ Then I should not be logged in to the back office
23
+ And I should see the error message "The employee does not exist, or the password provided is incorrect."
24
+
25
+ Scenario: The employee logs out from a legacy page
26
+ Given I am logged in to the back office as "admin"
27
+ When I log out of the back office
28
+ Then I should not be logged in to the back office
29
+
30
+ Scenario: The employee logs out from a new page
31
+ Given I am logged in to the back office as "admin"
32
+ And I open "Catalog > Products" in the back office menu
33
+ When I log out of the back office
34
+ Then I should not be logged in to the back office
35
+
36
+ Scenario: A limited employee lands on its own start page
37
+ Given I am logged in to the back office as "salesman"
38
+ Then the back office should greet "Sam"
39
+ And the back office page title should be "Orders"
40
+
41
+ Scenario: An address without the security token is not opened
42
+ Given I am logged in to the back office as "admin"
43
+ When I open the back office path "sell/catalog/products/" without the security token
44
+ Then I should see the invalid security token page
45
+ And I should see "I understand the risk"
46
+
47
+ Scenario: The same address with the security token opens
48
+ Given I am logged in to the back office as "admin"
49
+ When I open the back office path "sell/catalog/products/"
50
+ Then I should not see the invalid security token page
51
+ And the back office page title should be "Products"
@@ -0,0 +1,50 @@
1
+ @back-office @categories
2
+ Feature: Categories of the catalog
3
+ As an employee of the shop
4
+ I want to create, hide and delete categories
5
+ So that the catalog is organised
6
+
7
+ Background:
8
+ Given I am logged in to the back office as "admin"
9
+ And no "Webship test category" is left in "Catalog > Categories"
10
+
11
+ @critical
12
+ Scenario: Create, hide and delete a category
13
+ When I open "Catalog > Categories" in the back office menu
14
+ Then the back office page title should be "Categories"
15
+ And I should see "Clothes" in the list
16
+ When I press the back office toolbar button "Add new category"
17
+ Then the back office page title should be "New category"
18
+ When I fill in the back office field "Name" with "Webship test category"
19
+ Then the back office field "Friendly URL" should contain "webship-test-category"
20
+ When I save the back office form
21
+ Then I should see the success message "Successful creation"
22
+ And I should see "Webship test category" in the list
23
+ And the "Displayed" switch of the list row "Webship test category" should be on
24
+ When I flip the "Displayed" switch of the list row "Webship test category"
25
+ Then the "Displayed" switch of the list row "Webship test category" should be off
26
+ When I choose "Delete" for the list row "Webship test category"
27
+ Then I should see the confirmation dialog "What do you want to do with the products associated with this category?"
28
+ When I confirm the dialog
29
+ Then I should see the success message "Successful deletion"
30
+ And I should not see "Webship test category" in the list
31
+
32
+ Scenario: A category needs a name
33
+ When I open "Catalog > Categories" in the back office menu
34
+ And I press the back office toolbar button "Add new category"
35
+ And I save the back office form
36
+ Then I should see the field error "The field name is required at least in your default language."
37
+ And I should not see the success message "Successful creation"
38
+ And the back office page title should be "New category"
39
+
40
+ Scenario: Rename a category
41
+ When I open "Catalog > Categories" in the back office menu
42
+ And I press the back office toolbar button "Add new category"
43
+ And I fill in the back office field "Name" with "Webship test category"
44
+ And I save the back office form
45
+ And I choose "Edit" for the list row "Webship test category"
46
+ Then the back office field "Name" should contain "Webship test category"
47
+ When I fill in the back office field "Name" with "Webship test category renamed"
48
+ And I save the back office form
49
+ Then I should see the success message "Successful update"
50
+ And no "Webship test category" is left in "Catalog > Categories"