Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c1bcb3f
feat(dashboard): Allow creating customer and address inline on draft …
Ryrahul Jul 10, 2026
09dfe5b
fix(dashboard): Preserve selector tab state on draft order customer/a…
Ryrahul Jul 10, 2026
eea95a3
fix(dashboard): Address review feedback on draft order inline custome…
Ryrahul Jul 29, 2026
558700a
chore(dashboard): Re-extract i18n catalogs after rebase on master
Ryrahul Jul 29, 2026
656cb09
fix(dashboard): Prefill address form on modify page & add submitLabel…
Ryrahul Jul 29, 2026
a7f0fa7
refactor(dashboard): Move CreateCustomerInput & CreateAddressInput to…
Ryrahul Jul 29, 2026
bbc9074
refactor(dashboard): Use Order['shippingAddress'] for initialAddress …
Ryrahul Jul 29, 2026
1e819e4
refactor(dashboard): Extract inline setValuesForUpdate to named function
Ryrahul Jul 29, 2026
b87edd9
fix(dashboard): Address all remaining review feedback
Ryrahul Jul 29, 2026
52f9e0e
fix(dashboard): Make postalCode required to match Angular parity
Ryrahul Jul 29, 2026
441ffbd
test(dashboard): Add e2e test for modify-page address update path
Ryrahul Jul 29, 2026
d123545
fix(dashboard): Fix Base UI popover dismiss, add Cancel to customer f…
Ryrahul Jul 30, 2026
bcd5f25
fix(dashboard): Await mutations before closing popovers
Ryrahul Jul 30, 2026
fd41e05
fix(dashboard): Remove unnecessary reason check from dismiss prevention
Ryrahul Jul 30, 2026
b402da5
fix(dashboard): Align Select address and Remove buttons, add optional…
Ryrahul Jul 30, 2026
bc9ef52
chore: Remove dev-server/graphql-env.d.ts from PR diff
Ryrahul Jul 30, 2026
a422cdc
fix(dashboard): handle EmailAddressConflictError in draft order inlin…
Ryrahul Jul 31, 2026
c9c0a0e
chore: revert dev-server graphql-env.d.ts to upstream master
Ryrahul Jul 31, 2026
ee15d4a
Merge branch 'master' into feat/dashboard-draft-order-inline-customer…
biggamesmallworld Aug 3, 2026
9acfec8
chore(dashboard): re-extract i18n catalogs after merge with master
Ryrahul Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 123 additions & 1 deletion packages/dashboard/e2e/tests/sales/orders.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,89 @@ test.describe('Orders', () => {
await expect(page.getByRole('button', { name: /Select address/i })).toHaveCount(2);
});

// #4951 — parity with the Angular admin-ui: a draft order should allow creating a
// new customer inline (not just selecting an existing one).
test('should create a new customer inline on a draft order', async ({ page }) => {
test.setTimeout(60_000);

Comment on lines +300 to +301

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test skips client.login(), the next one does it. Pick one.

Suggested change
test.setTimeout(60_000);
test.setTimeout(60_000);
const client = new VendureAdminClient(page);
await client.login();

const client = new VendureAdminClient(page);
await client.login();

// Create a draft order
const lp = listPage(page);
await lp.goto();
await lp.expectLoaded();
await lp.newButton.click();
await expect(page).toHaveURL(/\/orders\/draft\//, { timeout: 10_000 });

// Open the customer selector (a tabbed popover) and switch to "Create new customer"
await page.getByRole('button', { name: /Select customer/i }).click();
const customerPopover = page.locator('[data-slot="popover-content"]');
await expect(customerPopover).toBeVisible();
await customerPopover.getByRole('tab', { name: /Create new customer/i }).click();

const email = `inline.customer.${Date.now()}@test.com`;
await customerPopover.getByLabel('First name').fill('Inline');
await customerPopover.getByLabel('Last name').fill('Customer');
await customerPopover.getByLabel('Email address').fill(email);
await customerPopover.getByRole('button', { name: /Create customer/i }).click();

// The mutation runs and the customer becomes set on the order
await page.waitForResponse(resp => resp.url().includes('/admin-api') && resp.status() === 200);
await expect(page.getByRole('button', { name: /Inline Customer/i })).toBeVisible({
timeout: 10_000,
});
});

// #4951 — parity with the Angular admin-ui: a draft order should allow entering a
// new, ad-hoc address inline (not just selecting from the customer's saved addresses).
test('should enter a new shipping address inline on a draft order', async ({ page }) => {
test.setTimeout(60_000);

const client = new VendureAdminClient(page);
await client.login();

// Create a draft order with a customer already set
const lp = listPage(page);
await lp.goto();
await lp.expectLoaded();
await lp.newButton.click();
await expect(page).toHaveURL(/\/orders\/draft\//, { timeout: 10_000 });

await page.getByRole('button', { name: /Select customer/i }).click();
const customerPopover = page.locator('[data-slot="popover-content"]');
await customerPopover.getByPlaceholder('Search customers...').fill('hayden');
const haydenOption = page.getByRole('option').filter({ hasText: /hayden/i });
await expect(haydenOption.first()).toBeVisible({ timeout: 5_000 });
await haydenOption.first().click();
await page.waitForResponse(resp => resp.url().includes('/admin-api') && resp.status() === 200);

// Open the shipping address selector and switch to the "New address" tab
await page
.getByRole('button', { name: /Select address/i })
.first()
.click();
// Scope to the address popover (identified by its "New address" tab) to avoid
// matching the customer popover that may still be animating closed.
const popover = page
.locator('[data-slot="popover-content"]')
.filter({ has: page.getByRole('tab', { name: /New address/i }) });
await expect(popover).toBeVisible({ timeout: 5_000 });
await popover.getByRole('tab', { name: /New address/i }).click();

// Fill the inline address form
await popover.getByLabel('Street Address').fill('99 Inline Road');
await popover.getByLabel('City').fill('Inlineton');
// Country is a Select — open and pick the first available country
await popover.getByRole('combobox').click();
await page.getByRole('option').first().click();
await popover.getByRole('button', { name: /Okay/i }).click();

// The new address is applied to the order
await page.waitForResponse(resp => resp.url().includes('/admin-api') && resp.status() === 200);
await expect(page.getByText('99 Inline Road')).toBeVisible({ timeout: 10_000 });
});

// #4393 — custom order history entry types should be displayed with key-value data
test('should display custom order history entry types', async ({ page }) => {
test.setTimeout(60_000);
Expand Down Expand Up @@ -348,7 +431,46 @@ test.describe('Orders', () => {

// The address selector popover should auto-open
await expect(page.locator('[data-slot="popover-content"]')).toBeVisible({ timeout: 5_000 });
await expect(page.getByText('Select an address')).toBeVisible();
await expect(page.getByRole('tab', { name: 'Existing address' })).toBeVisible();
});

// Regression test for the customFields blocker: editing an address on the modify page
// via the "New address" tab and clicking Preview should not produce a GraphQL variable
// coercion error (UpdateOrderAddressInput has no customFields field).
test('should update shipping address on modify page without GraphQL error', async ({ page }) => {
test.setTimeout(60_000);

const orderId = await createModifyingOrder(page);

await page.goto(`/orders/${orderId}/modify`);
await expect(page.getByRole('heading', { name: 'Modify order' })).toBeVisible({ timeout: 10_000 });

// Click "Edit" on shipping address
const editButtons = page.getByRole('button', { name: 'Edit' });
await editButtons.first().click();

// The address selector popover opens — switch to the "New address" tab
const popover = page.locator('[data-slot="popover-content"]');
await expect(popover).toBeVisible({ timeout: 5_000 });
await popover.getByRole('tab', { name: /New address/i }).click();

// Fill in a new address
await popover.getByLabel('Street Address').fill('456 Modified Ave');
await popover.getByLabel('City').fill('Modifiedton');
await popover.getByLabel('Postal Code').fill('99999');
// Country — open and pick the first available
await popover.getByRole('combobox').click();
await page.getByRole('option').first().click();
await popover.getByRole('button', { name: /Update address/i }).click();

// The address should appear in the modification summary
await expect(page.getByText('456 Modified Ave')).toBeVisible({ timeout: 10_000 });

// Click Preview — this is where the customFields blocker used to cause a GraphQL error
await page.getByRole('button', { name: /Preview/i }).click();

// The preview dialog should open without an error toast
await expect(page.getByRole('dialog')).toBeVisible({ timeout: 10_000 });
});

// #4393 — order modify page should show a "Recalculate shipping" checkbox
Expand Down
Loading
Loading