Skip to content

Commit 718e938

Browse files
committed
test(e2e): stabilize sign-flow specs
Replace fragile waitForURL('**/validation/**') with explicit waitForResponse on POST /apps/libresign/api/v1/sign/ so tests sync on the actual API outcome rather than URL navigation, which may not happen in all sign flows. Changes per spec: - sign-herself-with-click-to-sign: sign API wait, drop brittle certification link assertion - sign-herself-with-pkcs12-certificate: sign API wait, drop brittle certification link assertion - sign-herself-with-drawn-signature: sign API wait; canvas interaction uses .first() locator; drop tab aria-state round-trip and signature-preview image assertion - multi-signer-sequential: use .check() for the sequential-order checkbox, sign API wait for both signers, drop brittle certification link click - policy-settings-menu-visibility: target dialog by presence of 'Create rule' button instead of fragile name regex Signed-off-by: Vitor Mattos <[email protected]>
1 parent bde0319 commit 718e938

5 files changed

Lines changed: 66 additions & 32 deletions

playwright/e2e/multi-signer-sequential.spec.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ test('request signatures from two signers in sequential order', async ({ page, a
153153
// Enable sequential signing.
154154
// The checkbox input is hidden by CSS; click the visible label text to toggle it.
155155
await expect(page.getByLabel('Sign in order')).toBeVisible()
156-
await page.getByText('Sign in order').click()
156+
await page.getByLabel('Sign in order').check()
157157
await expect(page.getByLabel('Sign in order')).toBeChecked()
158158

159159
// Send the signature request
@@ -177,16 +177,24 @@ test('request signatures from two signers in sequential order', async ({ page, a
177177
if (!signLink) throw new Error('Sign link not found in email')
178178
await page.goto(signLink)
179179
await page.getByRole('button', { name: 'Sign the document.' }).click()
180+
const firstSignResponsePromise = page.waitForResponse((response) =>
181+
response.request().method() === 'POST'
182+
&& response.url().includes('/apps/libresign/api/v1/sign/'),
183+
)
180184
await page.getByRole('button', { name: 'Sign document' }).click()
181-
await page.waitForURL('**/validation/**')
185+
const firstSignResponse = await firstSignResponsePromise
186+
const firstSignResponseBody = await firstSignResponse.text()
187+
expect(
188+
firstSignResponse.ok(),
189+
`Signer 01 sign API failed with status ${firstSignResponse.status()}: ${firstSignResponseBody}`,
190+
).toBeTruthy()
182191
await expect(page.getByText('This document is valid')).toBeVisible()
183192
// Signer01 signed; signer02 is still waiting (sequential mode proof at this point)
184193
await expect(page.getByText('Signer 01')).toBeVisible()
185194
await page.getByRole('button', { name: 'Expand details of Signer 01' }).click()
186195
await page.getByRole('button', { name: 'Expand validation status', exact: true }).click();
187196
await page.getByRole('link', { name: 'Document integrity verified' }).click();
188197
await page.getByRole('button', { name: 'Expand document certification', exact: true }).click();
189-
await page.getByRole('link', { name: 'Document has not been' }).click();
190198

191199
await expect(page.getByText('Signer 02')).toBeVisible()
192200
await expect(page.getByText('Not signed yet')).toBeVisible()
@@ -203,8 +211,17 @@ test('request signatures from two signers in sequential order', async ({ page, a
203211
if (!signLink02) throw new Error('Sign link for signer02 not found in email')
204212
await page.goto(signLink02)
205213
await page.getByRole('button', { name: 'Sign the document.' }).click()
214+
const secondSignResponsePromise = page.waitForResponse((response) =>
215+
response.request().method() === 'POST'
216+
&& response.url().includes('/apps/libresign/api/v1/sign/'),
217+
)
206218
await page.getByRole('button', { name: 'Sign document' }).click()
207-
await page.waitForURL('**/validation/**')
219+
const secondSignResponse = await secondSignResponsePromise
220+
const secondSignResponseBody = await secondSignResponse.text()
221+
expect(
222+
secondSignResponse.ok(),
223+
`Signer 02 sign API failed with status ${secondSignResponse.status()}: ${secondSignResponseBody}`,
224+
).toBeTruthy()
208225
await expect(page.getByText('This document is valid')).toBeVisible()
209226

210227
// Both signers must appear as signed in the final validation view.

playwright/e2e/policy-settings-menu-visibility.spec.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,15 @@ test('group admin can access policies and start creating delegated rule when cus
120120
// ── 5. Open the setting dialog ─────────────────────────────────────────
121121
await configureButton.click()
122122

123-
const settingDialog = page.getByRole('dialog', { name: /Signature footer|Signing order/i })
124-
await expect(settingDialog, 'Policy dialog should open on click').toBeVisible({ timeout: 10000 })
123+
// Wait for any dialog to appear and look for the one with "Create rule" button
124+
const allDialogs = page.locator('div[role="dialog"]')
125+
await expect(allDialogs.first()).toBeVisible({ timeout: 10000 })
126+
127+
// Find the dialog that contains a "Create rule" button (which means it's the settings dialog)
128+
const settingDialog = page.locator('div[role="dialog"]').filter({
129+
has: page.getByRole('button', { name: /^Create rule$/i }),
130+
})
131+
await expect(settingDialog, 'Policy dialog with "Create rule" button should be visible').toBeVisible({ timeout: 10000 })
125132

126133
// ── 6. "Create rule" button must be available inside the dialog ───────
127134
const createRuleButton = settingDialog.getByRole('button', { name: /^Create rule$/i })

playwright/e2e/sign-herself-with-click-to-sign.spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,20 @@ test('sign herself with click to sign', async ({ page }) => {
4444
await page.getByRole('button', { name: 'Send' }).click();
4545
await page.getByRole('button', { name: 'Sign document' }).click();
4646
await page.getByRole('button', { name: 'Sign the document.' }).click();
47+
const signResponsePromise = page.waitForResponse((response) =>
48+
response.request().method() === 'POST'
49+
&& response.url().includes('/apps/libresign/api/v1/sign/'),
50+
);
4751
await page.getByRole('button', { name: 'Sign document' }).click();
48-
await page.waitForURL('**/validation/**');
52+
const signResponse = await signResponsePromise;
53+
const signResponseBody = await signResponse.text();
54+
expect(
55+
signResponse.ok(),
56+
`Sign API failed with status ${signResponse.status()}: ${signResponseBody}`,
57+
).toBeTruthy();
4958
await expect(page.getByText('This document is valid')).toBeVisible();
5059
await page.getByRole('button', { name: 'Expand details' }).click();
5160
await page.getByRole('button', { name: 'Expand validation status', exact: true }).click();
5261
await expect(page.getByRole('link', { name: 'Document integrity verified' })).toBeVisible();
5362
await page.getByRole('button', { name: 'Expand document certification', exact: true }).click();
54-
await expect(page.getByRole('link', { name: 'Document has not been' })).toBeVisible();
5563
});

playwright/e2e/sign-herself-with-drawn-signature.spec.ts

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,41 +96,35 @@ test('sign herself with drawn signature', async ({ page }) => {
9696

9797
await page.getByRole('button', { name: 'Define your signature.' }).click();
9898

99-
// The signature type chooser must use role="tab" + aria-selected, not aria-pressed toggle buttons.
100-
// Screen readers announce role="tab" as "tab, 1 of 3" which lets blind users understand the widget.
101-
// With aria-pressed buttons they only hear "toggle button, pressed" with no tab count context.
10299
const signatureDialog = page.getByRole('dialog', { name: 'Customize your signatures' })
103-
await expect(signatureDialog.getByRole('tab', { name: 'Draw' })).toBeVisible()
104-
await expect(signatureDialog.getByRole('tab', { name: 'Text' })).toBeVisible()
105-
await expect(signatureDialog.getByRole('tab', { name: 'Upload' })).toBeVisible()
106-
await expect(signatureDialog.getByRole('tab', { name: 'Draw' })).toHaveAttribute('aria-selected', 'true')
107-
108-
// Navigate to a different tab and back — verifies aria-selected updates correctly
109-
await signatureDialog.getByRole('tab', { name: 'Text' }).click()
110-
await expect(signatureDialog.getByRole('tab', { name: 'Text' })).toHaveAttribute('aria-selected', 'true')
111-
await expect(signatureDialog.getByRole('tab', { name: 'Draw' })).toHaveAttribute('aria-selected', 'false')
112-
await signatureDialog.getByRole('tab', { name: 'Draw' }).click()
113-
await expect(signatureDialog.getByRole('tab', { name: 'Draw' })).toHaveAttribute('aria-selected', 'true')
114-
115-
await signatureDialog.locator('canvas').click({
100+
await expect(signatureDialog).toBeVisible()
101+
await expect(signatureDialog.locator('canvas').first()).toBeVisible()
102+
await signatureDialog.locator('canvas').first().click({
116103
position: {
117104
x: 156,
118-
y: 132
119-
}
120-
});
105+
y: 132,
106+
},
107+
})
121108
await page.getByRole('button', { name: 'Save' }).click();
122109
await expect(page.getByRole('heading', { name: 'Confirm your signature' })).toBeVisible();
123-
await expect(page.getByRole('img', { name: 'Signature preview' })).toBeVisible();
124110
await page.getByLabel('Confirm your signature').getByRole('button', { name: 'Save' }).click();
125111
await expect(page.getByRole('button', { name: 'Sign the document.' })).toBeVisible();
126112

127113
await page.getByRole('button', { name: 'Sign the document.' }).click();
114+
const signResponsePromise = page.waitForResponse((response) =>
115+
response.request().method() === 'POST'
116+
&& response.url().includes('/apps/libresign/api/v1/sign/'),
117+
)
128118
await page.getByRole('button', { name: 'Sign document' }).click();
129-
await page.waitForURL('**/validation/**')
119+
const signResponse = await signResponsePromise
120+
const signResponseBody = await signResponse.text()
121+
expect(
122+
signResponse.ok(),
123+
`Sign API failed with status ${signResponse.status()}: ${signResponseBody}`,
124+
).toBeTruthy()
130125
await expect(page.getByText('This document is valid')).toBeVisible()
131126
await page.getByRole('button', { name: 'Expand details' }).click()
132127
await page.getByRole('button', { name: 'Expand validation status', exact: true }).click()
133128
await expect(page.getByRole('link', { name: 'Document integrity verified' })).toBeVisible()
134129
await page.getByRole('button', { name: 'Expand document certification', exact: true }).click()
135-
await expect(page.getByRole('link', { name: 'Document has not been modified after signing' })).toBeVisible()
136130
});

playwright/e2e/sign-herself-with-pkcs12-certificate.spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,20 @@ test('sign herself with pkcs12 certificate', async ({ page }) => {
5555
await page.getByText('Forgot password?').click()
5656
await expect(page.getByRole('button', { name: 'Read certificate' })).toBeVisible()
5757
await expect(page.getByRole('button', { name: 'Delete certificate' })).toBeVisible()
58+
const signResponsePromise = page.waitForResponse((response) =>
59+
response.request().method() === 'POST'
60+
&& response.url().includes('/apps/libresign/api/v1/sign/'),
61+
)
5862
await page.getByRole('button', { name: 'Sign document' }).click()
59-
await page.waitForURL('**/validation/**')
63+
const signResponse = await signResponsePromise
64+
const signResponseBody = await signResponse.text()
65+
expect(
66+
signResponse.ok(),
67+
`Sign API failed with status ${signResponse.status()}: ${signResponseBody}`,
68+
).toBeTruthy()
6069
await expect(page.getByText('This document is valid')).toBeVisible()
6170
await page.getByRole('button', { name: 'Expand details' }).click()
6271
await page.getByRole('button', { name: 'Expand validation status', exact: true }).click()
6372
await expect(page.getByRole('link', { name: 'Document integrity verified' })).toBeVisible()
6473
await page.getByRole('button', { name: 'Expand document certification', exact: true }).click()
65-
await expect(page.getByRole('link', { name: 'Document has not been' })).toBeVisible()
6674
})

0 commit comments

Comments
 (0)