@shopware-ag/acceptance-test-suite 1.0.0 → 1.1.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 CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Shopware
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.
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Shopware
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,357 +1,357 @@
1
- # Shopware Acceptance Test Suite
2
- This test suite is an extension to [Playwright](https://playwright.dev/) to easily create end-to-end and API acceptance tests for [Shopware](https://github.com/shopware/shopware). It provides several useful Playwright [fixtures](https://playwright.dev/docs/test-fixtures) to start testing with Shopware right away, including page contexts and [page objects](https://playwright.dev/docs/pom) for Storefront and Administration, API clients, test data creation and reusable test logic.
3
-
4
- ## Installation
5
- Start by creating your own [Playwright](https://playwright.dev/docs/intro) project.
6
-
7
- ```
8
- npm init playwright@latest
9
- ```
10
-
11
- Add the package for the Shopware Acceptance Test Suite to your project.
12
-
13
- ```
14
- npm install @shopware-ag/acceptance-test-suite
15
- ```
16
-
17
- Make sure to install Playwright and it's dependencies.
18
- ```
19
- npm install
20
- npx playwright install
21
- npx playwright install-deps
22
- ```
23
-
24
- ## Configuration
25
- The test suite is designed to test against any Shopware instance with pure API usage. To grant access to the instance under test you can use the following environment variables. You can decide between two authentication options - admin user or shopware integration (recommended).
26
-
27
- ```apacheconf
28
- # .env
29
-
30
- APP_URL="<url-to-the-shopware-instance>"
31
-
32
- # Authentication via integration
33
- SHOPWARE_ACCESS_KEY_ID="<your-shopware-integration-id>"
34
- SHOPWARE_SECRET_ACCESS_KEY="<your-shopware-integration-secret>"
35
-
36
- # Autentication via admin user
37
- SHOPWARE_ADMIN_USERNAME="<administrator-user-name>"
38
- SHOPWARE_ADMIN_PASSWORD="<administrator-user-password>"
39
- ```
40
-
41
- To ensure Playwright is referencing the right instance, you can use the same environment variable in your Playwright configuration.
42
-
43
- ```TypeScript
44
- // playwright.config.ts
45
-
46
- import { defineConfig } from '@playwright/test';
47
-
48
- export default defineConfig({
49
- use: {
50
- baseURL: process.env['APP_URL'],
51
- }
52
- });
53
- ```
54
-
55
- For more information about how to configure your Playwright project, have a look into the [official documentation](https://playwright.dev/docs/test-configuration).
56
-
57
- ## Usage
58
- The test suite uses the [extension system](https://playwright.dev/docs/extensibility) of Playwright and can be used as a full drop-in for Playwright. But, as you might also want to add your own extensions, the best way to use it is to create your own base test file and use it as the central reference for your test files. Add it to your project root or a specific fixture directory and name it whatever you like.
59
-
60
- ```TypeScript
61
- // BaseTestFile.ts
62
-
63
- import { test as base } from '@shopware-ag/acceptance-test-suite';
64
- import type { FixtureTypes } from '@shopware-ag/acceptance-test-suite';
65
-
66
- export * from '@shopware-ag/acceptance-test-suite';
67
-
68
- export const test = base.extend<FixtureTypes>({
69
-
70
- // Your own fixtures
71
-
72
- });
73
- ```
74
-
75
- Within your tests you can import the necessary dependencies from your base file.
76
-
77
- ```TypeScript
78
- // tests/MyFirstTest.spec.ts
79
-
80
- import { test, expect } from './../BaseTestFile';
81
-
82
- test('My first test scenario.', async ({ AdminApiContext, DefaultSalesChannel }) => {
83
-
84
- // Your test logic
85
-
86
- });
87
- ```
88
-
89
- In the example above you can see two Shopware specific fixtures that are used in the test, `AdminApiContext` and `DefaultSalesChannel`. Every fixture can be used as an argument within the test method. Read more about available fixtures in the next section.
90
-
91
- ## General Fixtures
92
-
93
- ### DefaultSalesChannel
94
- We try to encapsulate test execution within the system under test and make tests as deterministic as possible. The idea is, to have a separate sales channel created which is used to do tests within the standard Storefront. The `DefaultSalesChannel` fixture is a worker scoped fixture and is there to achieve exactly that. Using it will provide you with a new sales channel with default settings, including a default Storefront customer.
95
-
96
- **Properties**
97
- * `salesChannel`: The Shopware sales channel reference.
98
- * `customer`: A default Storefront customer reference.
99
- * `url`: The url to the sales channel Storefront.
100
-
101
- ### AdminApiContext
102
- This context provides a ready to use client for the Admin-API of Shopware. It is based on the standard Playwright [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext), but will handle authentication for you, so you can start doing API request to the Shopware instance under test right away. You can use it, for example, for test data creation or API testing. Learn more about the usage of the Shopware Admin-API in the [API documentation](https://shopware.stoplight.io/docs/admin-api).
103
-
104
- **Methods**
105
- * `get`
106
- * `post`
107
- * `patch`
108
- * `delete`
109
- * `fetch`
110
- * `head`
111
-
112
- **Usage**
113
- ```TypeScript
114
- import { test, expect } from './../BaseTestFile';
115
-
116
- test('Property group test scenario', async ({ AdminApiContext }) => {
117
-
118
- const response = await AdminApiContext.post('property-group?_response=1', {
119
- data: {
120
- name: 'Size',
121
- description: 'Size',
122
- displayType: 'text',
123
- sortingType: 'name',
124
- options: [{
125
- name: 'Small',
126
- }, {
127
- name: 'Medium',
128
- }, {
129
- name: 'Large',
130
- }],
131
- },
132
- });
133
-
134
- expect(response.ok()).toBeTruthy();
135
- });
136
- ```
137
-
138
- ### StoreApiContext
139
- This context provides a ready to use client for the Store-API of Shopware and is based on the standard Playwright [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext). You can do API calls on behalf of a Storefront user. Learn more about the usage of the Shopware Store-API in the [documentation](https://shopware.stoplight.io/docs/store-api/).
140
-
141
- Note that, other than the AdminApiContext, the StoreApiContext won't do an automated login of the shop customer. This is, because a Storefront user isn't always a registered user by default, and you might want to test this behaviour explicitly. You can use the `login` method to simply login as a registered shop customer.
142
-
143
- **Methods**
144
- * `login(user)`: Does a login of a customer and will store the login state for future requests.
145
- * `get`
146
- * `post`
147
- * `patch`
148
- * `delete`
149
- * `fetch`
150
- * `head`
151
-
152
- **Usage**
153
- ```TypeScript
154
- import { test, expect } from './../BaseTestFile';
155
-
156
- test('Store customer test scenario', async ({ StoreApiContext, DefaultSalesChannel }) => {
157
-
158
- // Login as the default customer.
159
- await StoreApiContext.login(DefaultSalesChannel.customer);
160
-
161
- // Create a new cart for the customer.
162
- const response = await StoreApiContext.post('checkout/cart', {
163
- data: { name: 'default-customer-cart' },
164
- });
165
-
166
- expect(response.ok()).toBeTruthy();
167
- });
168
- ```
169
-
170
- ### AdminPage
171
- This fixture provides a Playwright [page](https://playwright.dev/docs/api/class-page) context for the Shopware Administration. It creates a new admin user with an authenticated session. You can start testing within the Administration using this page right away.
172
-
173
- **Usage**
174
- ```TypeScript
175
- import { test, expect } from './../BaseTestFile';
176
-
177
- test('Shopware admin test scenario', async ({ AdminPage }) => {
178
-
179
- await AdminPage.goto('#/sw/product/index');
180
- await expect(AdminPage.locator('.sw-product-list__add-physical-button')).toBeVisible();
181
- });
182
- ```
183
-
184
- Note that this is just a very rough example. In most cases you won't use this page context directly, but maybe a [page-object](#page-objects) using this page.
185
-
186
- ### StorefrontPage
187
- This fixture provides a Playwright [page](https://playwright.dev/docs/api/class-page) context for the Shopware Storefront of the default sales channel.
188
-
189
- ## Page Objects
190
- Page objects can be helpful to simplify the usage of element selectors and make them available in a reusable way. They help you to organize page specific locators and provide helpers for interacting with a given page. Within our test suite we try to keep the page objects very simple and not to add too much logic to them. So most of the page objects resemble just a collection of element locators and maybe some little helper methods.
191
-
192
- There are several page objects to navigate the different pages of the Administration and Storefront. You can use them as any other fixture within your test. There is also a guide on page objects in the official Playwright [documentation](https://playwright.dev/docs/pom).
193
-
194
- **Usage**
195
- ```TypeScript
196
- import { test, expect } from './../BaseTestFile';
197
-
198
- test('Storefront cart test scenario', async ({ StorefrontCheckoutCart }) => {
199
-
200
- await StorefrontCheckoutCart.goTo();
201
- await expect(StorefrontCheckoutCart.grandTotalPrice).toHaveText('€100.00*');
202
- });
203
- ```
204
-
205
- You can get an overview of all available page objects in the [repository](https://github.com/shopware/acceptance-test-suite/tree/trunk/src/page-objects) of this test suite.
206
-
207
- ## Actor Pattern
208
- The actor pattern is a very simple concept that we added to our test suite. It is something that is not related to Playwright, but similar concepts exist in other testing frameworks. We implemented it, because we want to have reusable test logic that can be used in a human-readable form, without abstracting away Playwright as a framework. So you are totally free to use it or not. Any normal Playwright functionality will still be usable in your tests.
209
-
210
- The concept adds two new entities besides the already mentioned page objects.
211
-
212
- * **Actor**: A specific user with a given context performing actions (tasks) inside the application.
213
- * **Task**: A certain action performed by an actor.
214
- * **Pages**: A page of the application on which an actor performs a task.
215
-
216
- ### Actors
217
- The actor class is just a lightweight solution to simplify the execution of reusable test logic or the navigation to a certain page.
218
-
219
- **Properties**
220
- * `name`: The human-readable name of the actor.
221
- * `page`: A Playwright page context the actor is navigating.
222
-
223
- **Methods**
224
- * `goesTo`: Accepts a page object the actor should be navigating to.
225
- * `attemptsTo`: Accepts a "task" function with reusable test logic the actor should perform.
226
- * `expects`: A one-to-one export of the Playwright `expect` method to use it in the actor pattern.
227
-
228
- These methods lead to the following pattern:
229
-
230
- * The **actor** *goes to* a **page**.
231
- * The **actor** *attempts to* perform a certain **task**.
232
- * The **actor** *expects* a certain result.
233
-
234
- Translated into test code this pattern can look like this:
235
-
236
- ```TypeScript
237
- import { test } from './../BaseTestFile';
238
-
239
- test('Product detail test scenario', async ({
240
- ShopCustomer,
241
- StorefrontProductDetail,
242
- ProductData
243
- }) => {
244
-
245
- await ShopCustomer.goesTo(StorefrontProductDetail);
246
- await ShopCustomer.attemptsTo(AddProductToCart(ProductData));
247
- await ShopCustomer.expects(StorefrontProductDetail.offCanvasSummaryTotalPrice).toHaveText('€99.99*');
248
- });
249
- ```
250
-
251
- In this example you can see that this pattern creates tests that are very comprehensible, even for non-tech people. They also make it easier to abstract simple test logic that might be used in different scenarios into executable tasks, like adding a product to the cart. You can also see the usage of a data fixture (`ProductData`), which we will cover in a later chapter.
252
-
253
- The test suite offers two different actors by default:
254
-
255
- * `ShopCustomer`: A user that is navigating the Storefront and buying products.
256
- * `ShopAdmin`: A user that is managing Shopware via the Administration.
257
-
258
- ### Tasks
259
- Tasks are small chunks of reusable test logic that can be passed to the `attemptsTo` method of an actor. They are created via Playwright fixtures and have access to the same dependencies. Every executed task will automatically be wrapped in a test step of Playwright, so you get nicely structured reports of your tests.
260
-
261
- **Example**
262
- ```TypeScript
263
- import { test as base } from '@playwright/test';
264
- import type { FixtureTypes, Task } from '@shopware-ag/acceptance-test-suite';
265
-
266
- export const Login = base.extend<{ Login: Task }, FixtureTypes>({
267
- Login: async ({
268
- ShopCustomer,
269
- DefaultSalesChannel,
270
- StorefrontAccountLogin,
271
- StorefrontAccount,
272
- }, use)=> {
273
- const task = () => {
274
- return async function Login() {
275
- const { customer } = DefaultSalesChannel;
276
-
277
- await ShopCustomer.goesTo(StorefrontAccountLogin);
278
-
279
- await StorefrontAccountLogin.emailInput.fill(customer.email);
280
- await StorefrontAccountLogin.passwordInput.fill(customer.password);
281
- await StorefrontAccountLogin.loginButton.click();
282
-
283
- await ShopCustomer.expects(StorefrontAccount.personalDataCardTitle).toBeVisible();
284
- }
285
- };
286
-
287
- await use(task);
288
- },
289
- });
290
- ```
291
-
292
- This fixture is the "login" task and performs a simple Storefront login of the default customer. Everytime we need a logged in shop customer, we can simply reuse this logic in our test.
293
-
294
- ```TypeScript
295
- import { test } from './../BaseTestFile';
296
-
297
- test('Customer login test scenario', async ({ ShopCustomer, Login }) => {
298
-
299
- await ShopCustomer.attemptsTo(Login());
300
- });
301
- ```
302
-
303
- You can create your own tasks in the same way to make them available for the actor pattern. Every task is just a simple Playwright fixture containing a function call with the corresponding test logic. Make sure to merge your task fixtures with other fixtures you created in your base test file. You can use the `mergeTests` method of Playwright to combine several fixtures into one test extension.
304
-
305
- ## Data Fixtures
306
- We already covered a lot of interesting fixtures you can use to create your test scenario. One topic which is missing is test data. Most test scenarios will need some predefined state within the system under test to validate a certain behaviour. Within this test suite we use Playwright fixtures also to create necessary test data via API. The goal is to have no direct system dependencies like a database connection to the system under test.
307
-
308
- **Example**
309
- ```TypeScript
310
- import { test as base, expect } from '@playwright/test';
311
- import type { FixtureTypes } from '@shopware-ag/acceptance-test-suite';
312
-
313
- export const PropertiesData = base.extend<FixtureTypes>({
314
- PropertiesData: async ({ AdminApiContext }, use) => {
315
-
316
- const response = await AdminApiContext.post('property-group?_response=1', {
317
- data: {
318
- name: 'Size',
319
- description: 'Size',
320
- displayType: 'text',
321
- sortingType: 'name',
322
- options: [{
323
- name: 'Small',
324
- }, {
325
- name: 'Medium',
326
- }, {
327
- name: 'Large',
328
- }],
329
- },
330
- });
331
-
332
- expect(response.ok()).toBeTruthy();
333
-
334
- const { data: propertyGroup } = await response.json();
335
-
336
- await use(propertyGroup);
337
-
338
- const deleteResponse = await AdminApiContext.delete(`property-group/${propertyGroup.id}`);
339
- expect(deleteResponse.ok()).toBeTruthy();
340
- },
341
- });
342
- ```
343
-
344
- Here you can see a simple data fixture which will create a new property group in the Shopware instance under test via the Admin-API. The nice thing about Playwright fixtures is, that we can create some data and make it available within our test using the `use()` method and right afterward already clean up the data with a delete call. This enables us to have all operations regarding specific test data in one place with the opportunity to automatically clean up the data after test execution.
345
-
346
- You can simply make test data available in your test by using the fixture in your test method.
347
-
348
- ```TypeScript
349
- import { test } from './../BaseTestFile';
350
-
351
- test('Property group test scenario', async ({ PropertiesData }) => {
352
-
353
- // Do some testing with the property group from PropertiesData
354
- });
355
- ```
356
-
1
+ # Shopware Acceptance Test Suite
2
+ This test suite is an extension to [Playwright](https://playwright.dev/) to easily create end-to-end and API acceptance tests for [Shopware](https://github.com/shopware/shopware). It provides several useful Playwright [fixtures](https://playwright.dev/docs/test-fixtures) to start testing with Shopware right away, including page contexts and [page objects](https://playwright.dev/docs/pom) for Storefront and Administration, API clients, test data creation and reusable test logic.
3
+
4
+ ## Installation
5
+ Start by creating your own [Playwright](https://playwright.dev/docs/intro) project.
6
+
7
+ ```
8
+ npm init playwright@latest
9
+ ```
10
+
11
+ Add the package for the Shopware Acceptance Test Suite to your project.
12
+
13
+ ```
14
+ npm install @shopware-ag/acceptance-test-suite
15
+ ```
16
+
17
+ Make sure to install Playwright and it's dependencies.
18
+ ```
19
+ npm install
20
+ npx playwright install
21
+ npx playwright install-deps
22
+ ```
23
+
24
+ ## Configuration
25
+ The test suite is designed to test against any Shopware instance with pure API usage. To grant access to the instance under test you can use the following environment variables. You can decide between two authentication options - admin user or shopware integration (recommended).
26
+
27
+ ```apacheconf
28
+ # .env
29
+
30
+ APP_URL="<url-to-the-shopware-instance>"
31
+
32
+ # Authentication via integration
33
+ SHOPWARE_ACCESS_KEY_ID="<your-shopware-integration-id>"
34
+ SHOPWARE_SECRET_ACCESS_KEY="<your-shopware-integration-secret>"
35
+
36
+ # Autentication via admin user
37
+ SHOPWARE_ADMIN_USERNAME="<administrator-user-name>"
38
+ SHOPWARE_ADMIN_PASSWORD="<administrator-user-password>"
39
+ ```
40
+
41
+ To ensure Playwright is referencing the right instance, you can use the same environment variable in your Playwright configuration.
42
+
43
+ ```TypeScript
44
+ // playwright.config.ts
45
+
46
+ import { defineConfig } from '@playwright/test';
47
+
48
+ export default defineConfig({
49
+ use: {
50
+ baseURL: process.env['APP_URL'],
51
+ }
52
+ });
53
+ ```
54
+
55
+ For more information about how to configure your Playwright project, have a look into the [official documentation](https://playwright.dev/docs/test-configuration).
56
+
57
+ ## Usage
58
+ The test suite uses the [extension system](https://playwright.dev/docs/extensibility) of Playwright and can be used as a full drop-in for Playwright. But, as you might also want to add your own extensions, the best way to use it is to create your own base test file and use it as the central reference for your test files. Add it to your project root or a specific fixture directory and name it whatever you like.
59
+
60
+ ```TypeScript
61
+ // BaseTestFile.ts
62
+
63
+ import { test as base } from '@shopware-ag/acceptance-test-suite';
64
+ import type { FixtureTypes } from '@shopware-ag/acceptance-test-suite';
65
+
66
+ export * from '@shopware-ag/acceptance-test-suite';
67
+
68
+ export const test = base.extend<FixtureTypes>({
69
+
70
+ // Your own fixtures
71
+
72
+ });
73
+ ```
74
+
75
+ Within your tests you can import the necessary dependencies from your base file.
76
+
77
+ ```TypeScript
78
+ // tests/MyFirstTest.spec.ts
79
+
80
+ import { test, expect } from './../BaseTestFile';
81
+
82
+ test('My first test scenario.', async ({ AdminApiContext, DefaultSalesChannel }) => {
83
+
84
+ // Your test logic
85
+
86
+ });
87
+ ```
88
+
89
+ In the example above you can see two Shopware specific fixtures that are used in the test, `AdminApiContext` and `DefaultSalesChannel`. Every fixture can be used as an argument within the test method. Read more about available fixtures in the next section.
90
+
91
+ ## General Fixtures
92
+
93
+ ### DefaultSalesChannel
94
+ We try to encapsulate test execution within the system under test and make tests as deterministic as possible. The idea is, to have a separate sales channel created which is used to do tests within the standard Storefront. The `DefaultSalesChannel` fixture is a worker scoped fixture and is there to achieve exactly that. Using it will provide you with a new sales channel with default settings, including a default Storefront customer.
95
+
96
+ **Properties**
97
+ * `salesChannel`: The Shopware sales channel reference.
98
+ * `customer`: A default Storefront customer reference.
99
+ * `url`: The url to the sales channel Storefront.
100
+
101
+ ### AdminApiContext
102
+ This context provides a ready to use client for the Admin-API of Shopware. It is based on the standard Playwright [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext), but will handle authentication for you, so you can start doing API request to the Shopware instance under test right away. You can use it, for example, for test data creation or API testing. Learn more about the usage of the Shopware Admin-API in the [API documentation](https://shopware.stoplight.io/docs/admin-api).
103
+
104
+ **Methods**
105
+ * `get`
106
+ * `post`
107
+ * `patch`
108
+ * `delete`
109
+ * `fetch`
110
+ * `head`
111
+
112
+ **Usage**
113
+ ```TypeScript
114
+ import { test, expect } from './../BaseTestFile';
115
+
116
+ test('Property group test scenario', async ({ AdminApiContext }) => {
117
+
118
+ const response = await AdminApiContext.post('property-group?_response=1', {
119
+ data: {
120
+ name: 'Size',
121
+ description: 'Size',
122
+ displayType: 'text',
123
+ sortingType: 'name',
124
+ options: [{
125
+ name: 'Small',
126
+ }, {
127
+ name: 'Medium',
128
+ }, {
129
+ name: 'Large',
130
+ }],
131
+ },
132
+ });
133
+
134
+ expect(response.ok()).toBeTruthy();
135
+ });
136
+ ```
137
+
138
+ ### StoreApiContext
139
+ This context provides a ready to use client for the Store-API of Shopware and is based on the standard Playwright [APIRequestContext](https://playwright.dev/docs/api/class-apirequestcontext). You can do API calls on behalf of a Storefront user. Learn more about the usage of the Shopware Store-API in the [documentation](https://shopware.stoplight.io/docs/store-api/).
140
+
141
+ Note that, other than the AdminApiContext, the StoreApiContext won't do an automated login of the shop customer. This is, because a Storefront user isn't always a registered user by default, and you might want to test this behaviour explicitly. You can use the `login` method to simply login as a registered shop customer.
142
+
143
+ **Methods**
144
+ * `login(user)`: Does a login of a customer and will store the login state for future requests.
145
+ * `get`
146
+ * `post`
147
+ * `patch`
148
+ * `delete`
149
+ * `fetch`
150
+ * `head`
151
+
152
+ **Usage**
153
+ ```TypeScript
154
+ import { test, expect } from './../BaseTestFile';
155
+
156
+ test('Store customer test scenario', async ({ StoreApiContext, DefaultSalesChannel }) => {
157
+
158
+ // Login as the default customer.
159
+ await StoreApiContext.login(DefaultSalesChannel.customer);
160
+
161
+ // Create a new cart for the customer.
162
+ const response = await StoreApiContext.post('checkout/cart', {
163
+ data: { name: 'default-customer-cart' },
164
+ });
165
+
166
+ expect(response.ok()).toBeTruthy();
167
+ });
168
+ ```
169
+
170
+ ### AdminPage
171
+ This fixture provides a Playwright [page](https://playwright.dev/docs/api/class-page) context for the Shopware Administration. It creates a new admin user with an authenticated session. You can start testing within the Administration using this page right away.
172
+
173
+ **Usage**
174
+ ```TypeScript
175
+ import { test, expect } from './../BaseTestFile';
176
+
177
+ test('Shopware admin test scenario', async ({ AdminPage }) => {
178
+
179
+ await AdminPage.goto('#/sw/product/index');
180
+ await expect(AdminPage.locator('.sw-product-list__add-physical-button')).toBeVisible();
181
+ });
182
+ ```
183
+
184
+ Note that this is just a very rough example. In most cases you won't use this page context directly, but maybe a [page-object](#page-objects) using this page.
185
+
186
+ ### StorefrontPage
187
+ This fixture provides a Playwright [page](https://playwright.dev/docs/api/class-page) context for the Shopware Storefront of the default sales channel.
188
+
189
+ ## Page Objects
190
+ Page objects can be helpful to simplify the usage of element selectors and make them available in a reusable way. They help you to organize page specific locators and provide helpers for interacting with a given page. Within our test suite we try to keep the page objects very simple and not to add too much logic to them. So most of the page objects resemble just a collection of element locators and maybe some little helper methods.
191
+
192
+ There are several page objects to navigate the different pages of the Administration and Storefront. You can use them as any other fixture within your test. There is also a guide on page objects in the official Playwright [documentation](https://playwright.dev/docs/pom).
193
+
194
+ **Usage**
195
+ ```TypeScript
196
+ import { test, expect } from './../BaseTestFile';
197
+
198
+ test('Storefront cart test scenario', async ({ StorefrontCheckoutCart }) => {
199
+
200
+ await StorefrontCheckoutCart.goTo();
201
+ await expect(StorefrontCheckoutCart.grandTotalPrice).toHaveText('€100.00*');
202
+ });
203
+ ```
204
+
205
+ You can get an overview of all available page objects in the [repository](https://github.com/shopware/acceptance-test-suite/tree/trunk/src/page-objects) of this test suite.
206
+
207
+ ## Actor Pattern
208
+ The actor pattern is a very simple concept that we added to our test suite. It is something that is not related to Playwright, but similar concepts exist in other testing frameworks. We implemented it, because we want to have reusable test logic that can be used in a human-readable form, without abstracting away Playwright as a framework. So you are totally free to use it or not. Any normal Playwright functionality will still be usable in your tests.
209
+
210
+ The concept adds two new entities besides the already mentioned page objects.
211
+
212
+ * **Actor**: A specific user with a given context performing actions (tasks) inside the application.
213
+ * **Task**: A certain action performed by an actor.
214
+ * **Pages**: A page of the application on which an actor performs a task.
215
+
216
+ ### Actors
217
+ The actor class is just a lightweight solution to simplify the execution of reusable test logic or the navigation to a certain page.
218
+
219
+ **Properties**
220
+ * `name`: The human-readable name of the actor.
221
+ * `page`: A Playwright page context the actor is navigating.
222
+
223
+ **Methods**
224
+ * `goesTo`: Accepts a page object the actor should be navigating to.
225
+ * `attemptsTo`: Accepts a "task" function with reusable test logic the actor should perform.
226
+ * `expects`: A one-to-one export of the Playwright `expect` method to use it in the actor pattern.
227
+
228
+ These methods lead to the following pattern:
229
+
230
+ * The **actor** *goes to* a **page**.
231
+ * The **actor** *attempts to* perform a certain **task**.
232
+ * The **actor** *expects* a certain result.
233
+
234
+ Translated into test code this pattern can look like this:
235
+
236
+ ```TypeScript
237
+ import { test } from './../BaseTestFile';
238
+
239
+ test('Product detail test scenario', async ({
240
+ ShopCustomer,
241
+ StorefrontProductDetail,
242
+ ProductData
243
+ }) => {
244
+
245
+ await ShopCustomer.goesTo(StorefrontProductDetail);
246
+ await ShopCustomer.attemptsTo(AddProductToCart(ProductData));
247
+ await ShopCustomer.expects(StorefrontProductDetail.offCanvasSummaryTotalPrice).toHaveText('€99.99*');
248
+ });
249
+ ```
250
+
251
+ In this example you can see that this pattern creates tests that are very comprehensible, even for non-tech people. They also make it easier to abstract simple test logic that might be used in different scenarios into executable tasks, like adding a product to the cart. You can also see the usage of a data fixture (`ProductData`), which we will cover in a later chapter.
252
+
253
+ The test suite offers two different actors by default:
254
+
255
+ * `ShopCustomer`: A user that is navigating the Storefront and buying products.
256
+ * `ShopAdmin`: A user that is managing Shopware via the Administration.
257
+
258
+ ### Tasks
259
+ Tasks are small chunks of reusable test logic that can be passed to the `attemptsTo` method of an actor. They are created via Playwright fixtures and have access to the same dependencies. Every executed task will automatically be wrapped in a test step of Playwright, so you get nicely structured reports of your tests.
260
+
261
+ **Example**
262
+ ```TypeScript
263
+ import { test as base } from '@playwright/test';
264
+ import type { FixtureTypes, Task } from '@shopware-ag/acceptance-test-suite';
265
+
266
+ export const Login = base.extend<{ Login: Task }, FixtureTypes>({
267
+ Login: async ({
268
+ ShopCustomer,
269
+ DefaultSalesChannel,
270
+ StorefrontAccountLogin,
271
+ StorefrontAccount,
272
+ }, use)=> {
273
+ const task = () => {
274
+ return async function Login() {
275
+ const { customer } = DefaultSalesChannel;
276
+
277
+ await ShopCustomer.goesTo(StorefrontAccountLogin);
278
+
279
+ await StorefrontAccountLogin.emailInput.fill(customer.email);
280
+ await StorefrontAccountLogin.passwordInput.fill(customer.password);
281
+ await StorefrontAccountLogin.loginButton.click();
282
+
283
+ await ShopCustomer.expects(StorefrontAccount.personalDataCardTitle).toBeVisible();
284
+ }
285
+ };
286
+
287
+ await use(task);
288
+ },
289
+ });
290
+ ```
291
+
292
+ This fixture is the "login" task and performs a simple Storefront login of the default customer. Everytime we need a logged in shop customer, we can simply reuse this logic in our test.
293
+
294
+ ```TypeScript
295
+ import { test } from './../BaseTestFile';
296
+
297
+ test('Customer login test scenario', async ({ ShopCustomer, Login }) => {
298
+
299
+ await ShopCustomer.attemptsTo(Login());
300
+ });
301
+ ```
302
+
303
+ You can create your own tasks in the same way to make them available for the actor pattern. Every task is just a simple Playwright fixture containing a function call with the corresponding test logic. Make sure to merge your task fixtures with other fixtures you created in your base test file. You can use the `mergeTests` method of Playwright to combine several fixtures into one test extension.
304
+
305
+ ## Data Fixtures
306
+ We already covered a lot of interesting fixtures you can use to create your test scenario. One topic which is missing is test data. Most test scenarios will need some predefined state within the system under test to validate a certain behaviour. Within this test suite we use Playwright fixtures also to create necessary test data via API. The goal is to have no direct system dependencies like a database connection to the system under test.
307
+
308
+ **Example**
309
+ ```TypeScript
310
+ import { test as base, expect } from '@playwright/test';
311
+ import type { FixtureTypes } from '@shopware-ag/acceptance-test-suite';
312
+
313
+ export const PropertiesData = base.extend<FixtureTypes>({
314
+ PropertiesData: async ({ AdminApiContext }, use) => {
315
+
316
+ const response = await AdminApiContext.post('property-group?_response=1', {
317
+ data: {
318
+ name: 'Size',
319
+ description: 'Size',
320
+ displayType: 'text',
321
+ sortingType: 'name',
322
+ options: [{
323
+ name: 'Small',
324
+ }, {
325
+ name: 'Medium',
326
+ }, {
327
+ name: 'Large',
328
+ }],
329
+ },
330
+ });
331
+
332
+ expect(response.ok()).toBeTruthy();
333
+
334
+ const { data: propertyGroup } = await response.json();
335
+
336
+ await use(propertyGroup);
337
+
338
+ const deleteResponse = await AdminApiContext.delete(`property-group/${propertyGroup.id}`);
339
+ expect(deleteResponse.ok()).toBeTruthy();
340
+ },
341
+ });
342
+ ```
343
+
344
+ Here you can see a simple data fixture which will create a new property group in the Shopware instance under test via the Admin-API. The nice thing about Playwright fixtures is, that we can create some data and make it available within our test using the `use()` method and right afterward already clean up the data with a delete call. This enables us to have all operations regarding specific test data in one place with the opportunity to automatically clean up the data after test execution.
345
+
346
+ You can simply make test data available in your test by using the fixture in your test method.
347
+
348
+ ```TypeScript
349
+ import { test } from './../BaseTestFile';
350
+
351
+ test('Property group test scenario', async ({ PropertiesData }) => {
352
+
353
+ // Do some testing with the property group from PropertiesData
354
+ });
355
+ ```
356
+
357
357
  If you create your own data fixtures make sure to import and merge them in your base test file with other fixtures you created.
package/dist/index.d.mts CHANGED
@@ -351,7 +351,7 @@ declare class OrderDetail implements PageObject {
351
351
  readonly page: Page;
352
352
  readonly dataGridContextButton: Locator;
353
353
  readonly orderTag: Locator;
354
- private readonly orderData;
354
+ readonly orderData: components['schemas']['Order'];
355
355
  constructor(page: Page, orderData: components['schemas']['Order']);
356
356
  goTo(): Promise<void>;
357
357
  }
@@ -359,6 +359,7 @@ declare class OrderDetail implements PageObject {
359
359
  declare class CustomerDetail implements PageObject {
360
360
  readonly page: Page;
361
361
  readonly customerId: string | undefined;
362
+ readonly customer: components['schemas']['Customer'];
362
363
  readonly editButton: Locator;
363
364
  readonly generalTab: Locator;
364
365
  readonly accountCard: Locator;
package/dist/index.d.ts CHANGED
@@ -351,7 +351,7 @@ declare class OrderDetail implements PageObject {
351
351
  readonly page: Page;
352
352
  readonly dataGridContextButton: Locator;
353
353
  readonly orderTag: Locator;
354
- private readonly orderData;
354
+ readonly orderData: components['schemas']['Order'];
355
355
  constructor(page: Page, orderData: components['schemas']['Order']);
356
356
  goTo(): Promise<void>;
357
357
  }
@@ -359,6 +359,7 @@ declare class OrderDetail implements PageObject {
359
359
  declare class CustomerDetail implements PageObject {
360
360
  readonly page: Page;
361
361
  readonly customerId: string | undefined;
362
+ readonly customer: components['schemas']['Customer'];
362
363
  readonly editButton: Locator;
363
364
  readonly generalTab: Locator;
364
365
  readonly accountCard: Locator;
package/dist/index.mjs CHANGED
@@ -1255,10 +1255,12 @@ class CustomerDetail {
1255
1255
  constructor(page, customer) {
1256
1256
  this.page = page;
1257
1257
  __publicField$3(this, "customerId");
1258
+ __publicField$3(this, "customer");
1258
1259
  __publicField$3(this, "editButton");
1259
1260
  __publicField$3(this, "generalTab");
1260
1261
  __publicField$3(this, "accountCard");
1261
1262
  this.customerId = customer.id;
1263
+ this.customer = customer;
1262
1264
  this.editButton = page.getByRole("button", { name: "Edit" });
1263
1265
  this.generalTab = page.getByRole("link", { name: "General" });
1264
1266
  this.accountCard = page.locator(".sw-customer-card");
package/package.json CHANGED
@@ -1,54 +1,54 @@
1
- {
2
- "name": "@shopware-ag/acceptance-test-suite",
3
- "version": "1.0.0",
4
- "description": "Shopware Acceptance Test Suite",
5
- "author": "shopware AG",
6
- "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/shopware/acceptance-test-suite.git"
10
- },
11
- "keywords": [
12
- "shopware",
13
- "testing",
14
- "playwright",
15
- "integration",
16
- "fixtures",
17
- "test-data"
18
- ],
19
- "type": "module",
20
- "exports": {
21
- ".": {
22
- "types": "./dist/index.d.mts",
23
- "import": "./dist/index.mjs",
24
- "default": "./dist/index.mjs"
25
- }
26
- },
27
- "module": "./dist/index.mjs",
28
- "types": "./dist/index.d.ts",
29
- "files": [
30
- "dist"
31
- ],
32
- "scripts": {
33
- "lint": "eslint . --ext .ts",
34
- "lint:fix": "npm run lint --fix",
35
- "build": "npx unbuild",
36
- "prepublishOnly": "npm run build"
37
- },
38
- "dependencies": {
39
- "@playwright/test": "1.44.0",
40
- "@shopware/api-client": "0.5.0",
41
- "image-js": "0.35.5",
42
- "uuid": "9.0.1"
43
- },
44
- "devDependencies": {
45
- "@types/uuid": "9.0.8",
46
- "@typescript-eslint/eslint-plugin": "7.8.0",
47
- "@typescript-eslint/parser": "7.8.0",
48
- "eslint": "8.56.0",
49
- "eslint-plugin-playwright": "1.6.0",
50
- "ts-node": "10.9.2",
51
- "typescript": "5.4.5",
52
- "unbuild": "2.0.0"
53
- }
54
- }
1
+ {
2
+ "name": "@shopware-ag/acceptance-test-suite",
3
+ "version": "1.1.1",
4
+ "description": "Shopware Acceptance Test Suite",
5
+ "author": "shopware AG",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/shopware/acceptance-test-suite.git"
10
+ },
11
+ "keywords": [
12
+ "shopware",
13
+ "testing",
14
+ "playwright",
15
+ "integration",
16
+ "fixtures",
17
+ "test-data"
18
+ ],
19
+ "type": "module",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.mts",
23
+ "import": "./dist/index.mjs",
24
+ "default": "./dist/index.mjs"
25
+ }
26
+ },
27
+ "module": "./dist/index.mjs",
28
+ "types": "./dist/index.d.ts",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "scripts": {
33
+ "lint": "eslint . --ext .ts",
34
+ "lint:fix": "npm run lint --fix",
35
+ "build": "npx unbuild",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "dependencies": {
39
+ "@playwright/test": "1.44.0",
40
+ "@shopware/api-client": "0.5.0",
41
+ "image-js": "0.35.5",
42
+ "uuid": "9.0.1"
43
+ },
44
+ "devDependencies": {
45
+ "@types/uuid": "9.0.8",
46
+ "@typescript-eslint/eslint-plugin": "7.8.0",
47
+ "@typescript-eslint/parser": "7.8.0",
48
+ "eslint": "8.56.0",
49
+ "eslint-plugin-playwright": "1.6.0",
50
+ "ts-node": "10.9.2",
51
+ "typescript": "5.4.5",
52
+ "unbuild": "2.0.0"
53
+ }
54
+ }