Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
6c59031
CC-39280 Assert a published cms page on the storefront
stereomon Aug 21, 2026
9074fa6
CC-39280 Assert the cms content block on the storefront too
stereomon Aug 21, 2026
adb212c
CC-39280 Cover ACL deny precedence and deactivated-user login
stereomon Aug 21, 2026
f0af7f7
CC-39280 Crawl every back-office navigation node
stereomon Aug 22, 2026
ac9b258
CC-39280 Assert a back-office profile edit reaches the storefront
stereomon Aug 22, 2026
c7a0da8
CC-39280 Cover account page reachability and address deletion
stereomon Aug 22, 2026
db91565
CC-39280 Assert a back-office address reaches the storefront
stereomon Aug 22, 2026
025441a
CC-39280 Replace the account navigation crawl with the pages the sour…
stereomon Aug 22, 2026
85f8e44
CC-39280 Cover glossary translation create and edit in the back office
stereomon Aug 22, 2026
b375fdd
CC-39280 Add storefront customer impersonation for agents
stereomon Aug 22, 2026
f5d091d
CC-39280 Place an order as an agent for an impersonated customer
stereomon Aug 22, 2026
8b707dc
CC-39280 Create a company user on the storefront and check its role
stereomon Aug 22, 2026
3f5ac41
CC-39280 Assert an order splits into one shipment per delivery address
stereomon Aug 22, 2026
d50403f
CC-39280 Assert the handover, not a 500, when assistance ends
stereomon Aug 22, 2026
bfa1b5b
CC-39280 Fix the business-unit select and the glossary row lookup
stereomon Aug 22, 2026
5a01584
CC-39280 Cover the warehouse-user flag and the picking OMS walk in th…
stereomon Aug 23, 2026
b19f680
CC-39280 Make the warehouse-user check retry-safe and own the state wait
stereomon Aug 23, 2026
3d56b23
CC-39280 Run the picking OMS walk on suite only
stereomon Aug 23, 2026
4751e22
CC-39280 Correct why the picking walk is gated to suite
stereomon Aug 23, 2026
c151499
CC-39280 Build the picking order stock in a warehouse with a picking …
stereomon Aug 24, 2026
d0db398
CC-39280 Scope the order-item state wait to the item under test
stereomon Aug 24, 2026
adbc99c
CC-39280 Name one order item in the picking walk title
stereomon Aug 24, 2026
cb4286f
Merge warehouse batch into the migration branch
stereomon Aug 24, 2026
87dfbd1
CC-39280 Build the company structure in the back office
stereomon Aug 24, 2026
25ba62c
CC-39280 Name the company-structure test after what it asserts
stereomon Aug 24, 2026
9128fed
CC-39280 Tag the company-structure specs for Agent Assist
stereomon Aug 24, 2026
76f44e2
CC-39280 State the company-select re-fetch once, not three times
stereomon Aug 24, 2026
185833c
CC-39280 Wait for the company suggest on the company-role form
stereomon Aug 24, 2026
0427bc6
Merge company batch into the migration branch
stereomon Aug 24, 2026
f4bc096
CC-39280 Order the navigation smoke body comments Arrange, Act, Assert
stereomon Aug 24, 2026
307e414
CC-39280 Skip the impersonated checkout on the b2b storefronts
stereomon Aug 24, 2026
74f437b
CC-39280 Derive the glossary key inside the test that creates it
stereomon Aug 24, 2026
05be7c0
CC-39280 Shorten the glossary key comment to the two load-bearing lines
stereomon Aug 24, 2026
e8664e5
CC-39280 Settle the glossary table row count before picking a row
stereomon Aug 24, 2026
2402dc2
Merge administration batch into the migration branch
stereomon Aug 24, 2026
ab927e5
CC-39280 Cover the data exchange api specification download
stereomon Aug 24, 2026
944e157
CC-39280 Cover the data exchange api configuration form
stereomon Aug 24, 2026
0d59ed9
CC-39280 Cover the global minimum and maximum order thresholds
stereomon Aug 24, 2026
a528646
CC-39280 Cover the storefront half of discounts and promotions
stereomon Aug 24, 2026
443e70e
CC-39280 Establish the specification baseline instead of assuming it
stereomon Aug 24, 2026
a712a89
Merge platform batch into the migration branch
stereomon Aug 24, 2026
ffb69ab
CC-39280 Cover the guest halves of the checkout discount and split-de…
stereomon Aug 24, 2026
d7e891b
CC-39280 Cover cart comments through checkout and both checkout authe…
stereomon Aug 24, 2026
daa76af
CC-39280 Cover checkout address re-editing and business unit addresses
stereomon Aug 24, 2026
23963db
CC-39280 Cover the shared-cart external link and author the multi-mer…
stereomon Aug 24, 2026
ef63a3b
CC-39280 Cover the cart approval process
stereomon Aug 24, 2026
9724eeb
CC-39280 Cover the quote request lifecycle
stereomon Aug 24, 2026
6ddc400
CC-39280 Arrange the multi-merchant cart through the storefront API
stereomon Aug 24, 2026
da8c0dc
CC-39280 Give the multi-merchant fixture's offer products their own s…
stereomon Aug 24, 2026
a412e99
CC-39280 Prove the multi-merchant order locally
stereomon Aug 24, 2026
8bb53ed
CC-39280 Author click and collect
stereomon Aug 24, 2026
6abc9b5
CC-39280 Prove click and collect locally
stereomon Aug 24, 2026
27f0129
CC-39280 Give the guest discount test its own voucher code
stereomon Aug 24, 2026
ae752e8
CC-39280 Run click and collect only where the service point finder ex…
stereomon Aug 24, 2026
31b0f8d
CC-39280 Name the two migrated tests Given/When/Then
stereomon Aug 24, 2026
8a5725a
Merge checkout batch into the migration branch
stereomon Aug 24, 2026
d6725ca
CC-39280 Prove a guest is kept out of the account area
stereomon Aug 25, 2026
14e2ffc
CC-39280 Prove products land in the wishlist the customer picked
stereomon Aug 25, 2026
302df25
CC-39280 Prove a wishlist keeps each merchant offer apart
stereomon Aug 25, 2026
0a105ca
CC-39280 Prove a shopping list keeps each merchant offer apart
stereomon Aug 25, 2026
982ebcd
CC-39280 Prove a shared shopping list reaches the colleague
stereomon Aug 25, 2026
31ae795
CC-39280 Prove a shared cart can be ordered by the colleague
stereomon Aug 25, 2026
977c212
CC-39280 Prove quick order carries merchants into order and reorder
stereomon Aug 25, 2026
9c5b057
CC-39280 Prove a customer can act for either of two business units
stereomon Aug 25, 2026
d42531d
CC-39280 Name the customer specs Given/When/Then and make their creat…
stereomon Aug 25, 2026
74aff3b
Merge customer batch into the migration branch
stereomon Aug 25, 2026
6a00574
CC-39280 Prove related products show on the detail page and nowhere else
stereomon Aug 25, 2026
e6537f9
CC-39280 Prove a published label reaches the catalog card and the det…
stereomon Aug 25, 2026
6e3c96a
CC-39280 Build a product set in the back office and prove it end to e…
stereomon Aug 25, 2026
4f39090
CC-39280 Prove a product set opens from the overview and carries its …
stereomon Aug 25, 2026
384b3ae
CC-39280 Configure two bundles, double one and prove three reach the …
stereomon Aug 25, 2026
1ce9dad
Merge merchandising batch into the migration branch
stereomon Aug 25, 2026
1257385
CC-39280 Port the storefront order cancellation journey to Cypress
stereomon Aug 25, 2026
5121adf
CC-39280 Port the per-item order refund journey to Cypress
stereomon Aug 25, 2026
9f10fc3
CC-39280 Port the storefront order comment journey to Cypress
stereomon Aug 25, 2026
a169f8e
CC-39280 Port back-office shipment create and edit to Cypress
stereomon Aug 25, 2026
82fc72d
CC-39280 Port the storefront return creation journey to Cypress
stereomon Aug 25, 2026
26031e5
CC-39280 Port the configurable product order journey to Cypress
stereomon Aug 25, 2026
4cf1900
CC-39280 Give the order refund and cancellation fixtures retry headroom
stereomon Aug 25, 2026
63db03c
CC-39280 Open the refunded order by its reference
stereomon Aug 25, 2026
28e1632
Merge order batch into the migration branch
stereomon Aug 25, 2026
b851247
CC-39280 Port the product detail page visibility journey to Cypress
stereomon Aug 25, 2026
c10b28c
CC-39280 Port the customer specific prices journey to Cypress
stereomon Aug 25, 2026
a4ad1be
CC-39280 Port the original price journey to Cypress
stereomon Aug 25, 2026
f2c6a9e
CC-39280 Port the discontinued and alternative products journey to Cy…
stereomon Aug 25, 2026
fd7e403
CC-39280 Port the catalog quick add to cart journey to Cypress
stereomon Aug 25, 2026
66a6f22
CC-39280 Port the volume prices journey to Cypress
stereomon Aug 25, 2026
cc66d80
CC-39280 Port the measurement unit checkout journey to Cypress
stereomon Aug 25, 2026
b8c9947
CC-39280 Port the packaging unit checkout journey to Cypress
stereomon Aug 25, 2026
ae84487
CC-39280 Port the product bundle checkout journey to Cypress
stereomon Aug 25, 2026
88833af
CC-39280 Port the catalog browsing journey to Cypress
stereomon Aug 25, 2026
09ab94b
CC-39280 Port the back in stock notification journey to Cypress
stereomon Aug 25, 2026
97b400f
CC-39280 Port the configurable product checkout journey to Cypress
stereomon Aug 25, 2026
04860c8
CC-39280 Port the configurable product wishlist journey to Cypress
stereomon Aug 25, 2026
7059344
CC-39280 Port the configurable product shopping list journey to Cypress
stereomon Aug 25, 2026
e69bd6f
CC-39280 Resolve the catalog result click in a single query
stereomon Aug 25, 2026
78c2dd8
CC-39280 Port the configurable product request for quote journey to C…
stereomon Aug 25, 2026
44d721a
CC-39280 Port the product lifecycle management journey to Cypress
stereomon Aug 25, 2026
1fbf402
CC-39280 Port the product restrictions journey to Cypress
stereomon Aug 25, 2026
4ed485c
CC-39280 Port the availability calculation journey to Cypress
stereomon Aug 25, 2026
6abd1a2
CC-39280 Make the deactivation spec prove the product was listed first
stereomon Aug 25, 2026
f3d6475
CC-39280 Name the action in the unconfigured-cart title
stereomon Aug 25, 2026
e1fc9ee
Merge product batch into the migration branch
stereomon Aug 25, 2026
ed76b2d
test(multistore): cover cms page store assignment and its 404 after u…
stereomon Aug 26, 2026
ee6b10a
test(multistore): cover per-store product pricing and the 404 after u…
stereomon Aug 26, 2026
3b40a4a
test(multistore): cover store-scoped product offers and their removal…
stereomon Aug 26, 2026
d43c53a
test(dms): cover the end-to-end usability of a newly created store
stereomon Aug 26, 2026
413336f
fix(multistore): let the unassign specs survive a retry
stereomon Aug 26, 2026
9c393e0
Merge store batch into the migration branch
stereomon Aug 26, 2026
7d0dbe8
Merge remote-tracking branch 'origin/master' into feature/cc-39273/cc…
stereomon Sep 21, 2026
cea4636
CC-39280 Port the merchant profile update and store status journeys t…
stereomon Sep 21, 2026
955421c
CC-39280 Port the back office merchant deactivation and crud journeys…
stereomon Sep 21, 2026
88c9ebb
CC-39280 Port the offer approval journey to Cypress
stereomon Sep 21, 2026
e7f4ff2
CC-39280 Port the back office merchant product and offer view to Cypress
stereomon Sep 21, 2026
dfa569b
CC-39280 Port the merchant product original price to Cypress
stereomon Sep 21, 2026
115c625
CC-39280 Port the merchant product volume prices to Cypress
stereomon Sep 21, 2026
c423194
CC-39280 Port the merchant offer volume prices to Cypress
stereomon Sep 21, 2026
2aef689
CC-39280 Port the back office merchant user management to Cypress
stereomon Sep 21, 2026
5d4a864
CC-39280 Port the offer availability calculation to Cypress
stereomon Sep 21, 2026
923f217
CC-39280 Port the merchant customer specific prices to Cypress
stereomon Sep 21, 2026
9f0f312
CC-39280 Drop the unused b2c fixture for customer specific prices
stereomon Sep 21, 2026
8f89d0b
CC-39280 Port the merchant portal my account journey to Cypress
stereomon Sep 21, 2026
9451e63
CC-39280 Port the merchant catalog facet to Cypress
stereomon Sep 21, 2026
db85905
CC-39280 Port the merchant product creation and approval to Cypress
stereomon Sep 21, 2026
c4a2886
CC-39280 Port the merchant product management to Cypress
stereomon Sep 21, 2026
a0390fd
CC-39280 Port the merchant offer creation to Cypress
stereomon Sep 21, 2026
ec2c28f
CC-39280 Port the merchant order fulfilment to Cypress
stereomon Sep 21, 2026
676d2cb
CC-39280 Read page bodies through page objects in the merchant specs
stereomon Sep 21, 2026
302f3df
CC-39280 Make the merchant portal profile tab and product search wait…
stereomon Sep 22, 2026
556ce53
CC-39280 Pin the merchant user locale and name the rendered portal ta…
stereomon Sep 22, 2026
5311f26
CC-39280 Confirm arrival on the merchant profile page before opening …
stereomon Sep 22, 2026
ed6b2d2
CC-39280 Name the page the merchant portal really rendered when its t…
stereomon Sep 22, 2026
131cdd7
CC-39280 Report the merchant portal tab labels that were rendered whe…
stereomon Sep 22, 2026
816c054
CC-39280 Wait for the merchant profile component to upgrade before re…
stereomon Sep 22, 2026
e34e01f
CC-39280 Format the merchant fixture files with Prettier
stereomon Sep 22, 2026
ecc12cb
CC-39280 Quarantine the three merchant portal profile specs and minim…
stereomon Sep 22, 2026
d8bd34b
CC-40647 replace button element - fix
Nidhognit Sep 30, 2026
4e39dd5
Merge remote-tracking branch 'origin/master' into feature/cc-39273/cc…
stereomon Oct 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 8 additions & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from 'cypress';
import dotenv from 'dotenv';
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';

dotenv.config();

Expand Down Expand Up @@ -44,6 +44,13 @@ export default defineConfig({
isFileExists(filename: string): boolean {
return existsSync(filename);
},
deleteFile(filename: string): null {
if (existsSync(filename)) {
rmSync(filename);
}

return null;
},
});
if (!config.env.grepTags) {
config.env.grepFilterSpecs = false;
Expand Down
33 changes: 32 additions & 1 deletion cypress/e2e/backoffice/acl/acl-navigation-access.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { container } from '@utils';
import { AclNavigationAccessDynamicFixtures } from '@interfaces/backoffice';
import { AclNavigationAccessScenario } from '@scenarios/backoffice';
import { AclDeniedPage, LoginPage } from '@pages/backoffice';
import { AclNavigationAccessScenario, UserLoginScenario } from '@scenarios/backoffice';

describe(
'ACL navigation access',
Expand All @@ -12,6 +13,9 @@ describe(
}

const aclNavigationAccessScenario = container.get(AclNavigationAccessScenario);
const userLoginScenario = container.get(UserLoginScenario);
const aclDeniedPage = container.get(AclDeniedPage);
const loginPage = container.get(LoginPage);
const password = 'Change123@_!';

it('single-role user with product-management permissions', (): void => {
Expand All @@ -37,5 +41,32 @@ describe(
deniedPaths: ['/sales/detail', '/cms-gui/list-page/index', '/user', '/product-management'],
});
});

it('should deny an action for a role with an explicit deny rule', (): void => {
// Arrange
const { dynamicFixtures } = Cypress.env() as { dynamicFixtures: AclNavigationAccessDynamicFixtures };

// The user's other role allows every bundle, so only the deny rule can stop this request —
// which is what makes it a test of deny precedence rather than of a missing allow.
userLoginScenario.execute({ username: dynamicFixtures.deniedActionUser.username, password: password });

// Act
cy.visitBackoffice('/product-attribute-gui/attribute/create');

// Assert
aclDeniedPage.getAccessDeniedTitle().should('have.text', 'Access denied');
});

it('should refuse login for a deactivated user', (): void => {
// Arrange
const { dynamicFixtures } = Cypress.env() as { dynamicFixtures: AclNavigationAccessDynamicFixtures };
loginPage.visit();

// Act
loginPage.login({ username: dynamicFixtures.blockedUser.username, password: password });

// Assert
loginPage.getErrorMessage().should('contain.text', 'Authentication failed!');
});
}
);
62 changes: 62 additions & 0 deletions cypress/e2e/backoffice/administration/glossary-management.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { container } from '@utils';
import { GlossaryManagementDynamicFixtures, GlossaryManagementStaticFixtures } from '@interfaces/backoffice';
import { GlossaryFormPage, GlossaryListPage } from '@pages/backoffice';
import { UserLoginScenario } from '@scenarios/backoffice';

describe(
'glossary management',
{ tags: ['@backoffice', 'glossary', 'spryker-core-back-office', 'spryker-core'] },
(): void => {
const glossaryListPage = container.get(GlossaryListPage);
const glossaryFormPage = container.get(GlossaryFormPage);
const userLoginScenario = container.get(UserLoginScenario);

let staticFixtures: GlossaryManagementStaticFixtures;
let dynamicFixtures: GlossaryManagementDynamicFixtures;

// A key of its own per attempt, so the test never edits a translation the storefront renders.
// Derived in the creating test, not in before(), which a Cypress retry does not re-run.
let glossaryKey: string;

before((): void => {
({ dynamicFixtures, staticFixtures } = Cypress.env());
});

beforeEach((): void => {
userLoginScenario.execute({
username: dynamicFixtures.rootUser.username,
password: staticFixtures.defaultPassword,
});
});

it('should create a translation and list it', (): void => {
// Arrange
glossaryKey = `${staticFixtures.glossaryKeyPrefix}.${Date.now()}`;
glossaryListPage.visit();

// Act
glossaryListPage.clickCreateTranslation();
glossaryFormPage.create({ glossaryKey: glossaryKey, translation: staticFixtures.translation });

// Assert
glossaryListPage.visit();
glossaryListPage.findTranslation(glossaryKey).should('contain.text', glossaryKey);
});

it('should update the translation of an existing key', (): void => {
// Arrange
glossaryListPage.visit();
glossaryListPage.edit(glossaryKey);

// Act
glossaryFormPage.update(staticFixtures.updatedTranslation);

// Assert
glossaryListPage.visit();
glossaryListPage.edit(glossaryKey);
glossaryFormPage.getLocaleTextareas().each(($textarea) => {
cy.wrap($textarea).should('have.value', staticFixtures.updatedTranslation);
});
});
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { container } from '@utils';
import {
CompanyStructureCreationDynamicFixtures,
CompanyStructureCreationStaticFixtures,
} from '@interfaces/backoffice';
import {
ActionEnum,
CompanyBusinessUnitCreatePage,
CompanyCreatePage,
CompanyListPage,
CompanyRoleCreatePage,
CompanyUserCreatePage,
CompanyUserListPage,
} from '@pages/backoffice';
import { UserLoginScenario } from '@scenarios/backoffice';
import { ImpersonateCustomerScenario } from '@scenarios/yves';

describe(
'company structure creation',
{
tags: [
'@backoffice',
'@company-account',
'company-account',
'spryker-core-back-office',
'spryker-core',
'agent-assist',
'acl',
],
},
(): void => {
if (['b2c', 'b2c-mp'].includes(Cypress.env('repositoryId'))) {
it.skip('skipped because company accounts exist only in suite, b2b and b2b-mp', () => {});
return;
}

const userLoginScenario = container.get(UserLoginScenario);
const impersonateCustomerScenario = container.get(ImpersonateCustomerScenario);
const companyCreatePage = container.get(CompanyCreatePage);
const companyListPage = container.get(CompanyListPage);
const companyBusinessUnitCreatePage = container.get(CompanyBusinessUnitCreatePage);
const companyRoleCreatePage = container.get(CompanyRoleCreatePage);
const companyUserCreatePage = container.get(CompanyUserCreatePage);
const companyUserListPage = container.get(CompanyUserListPage);

let staticFixtures: CompanyStructureCreationStaticFixtures;
let dynamicFixtures: CompanyStructureCreationDynamicFixtures;

let companyName: string;
let businessUnitName: string;
let roleName: string;
let companyUserEmail: string;
let companyUserLastName: string;

before((): void => {
({ dynamicFixtures, staticFixtures } = Cypress.env());

const unique = Date.now();
companyName = `Company${unique}`;
businessUnitName = `BusinessUnit${unique}`;
roleName = `Role${unique}`;
companyUserEmail = `company.user.${unique}@spryker.local`;
companyUserLastName = `User${unique}`;
});

it('should list the new company user under its company when the company structure is built in the back office', (): void => {
// Arrange
userLoginScenario.execute({
username: dynamicFixtures.rootUser.username,
password: staticFixtures.defaultPassword,
});

// Act
companyCreatePage.visit();
companyCreatePage.create(companyName);

// A company is created inactive and pending, and only an active approved one can carry users.
companyListPage.visit();
companyListPage.update({ query: companyName, action: ActionEnum.activate });
companyListPage.visit();
companyListPage.update({ query: companyName, action: ActionEnum.approve });

companyBusinessUnitCreatePage.visit();
companyBusinessUnitCreatePage.create({ companyName: companyName, name: businessUnitName });

companyRoleCreatePage.visit();
companyRoleCreatePage.create({
companyName: companyName,
name: roleName,
permissionName: staticFixtures.seeCompanyUsersPermissionName,
});

companyUserCreatePage.visit();
companyUserCreatePage.create({
companyName: companyName,
businessUnitName: businessUnitName,
roleName: roleName,
email: companyUserEmail,
salutation: 'Ms',
firstName: 'Company',
lastName: companyUserLastName,
gender: 'Female',
});

// Assert
companyUserListPage.visit();
companyUserListPage.findByCompanyName(companyName).should('contain.text', companyUserLastName);
});

it('created company user should reach only what its role allows', (): void => {
// Arrange
// Nothing knows the new company user's password, so the agent switches into their session.
impersonateCustomerScenario.execute({
agentUsername: dynamicFixtures.agentUser.username,
agentPassword: staticFixtures.defaultPassword,
customerEmail: companyUserEmail,
});

// Act
cy.visit(staticFixtures.companyUserPagePath, { failOnStatusCode: false });

// Assert
cy.url().should('include', staticFixtures.companyUserPagePath);

// Act
cy.visit(staticFixtures.companyRolePagePath, { failOnStatusCode: false });

// Assert
cy.url().should('include', '403');
});
}
);
Loading
Loading