# Instructions - Following Playwright test failed. - Explain why, be concise, respect Playwright best practices. - Provide a snippet of code with the fix, if possible. # Test info - Name: src/manager/tests/e2e/invoice/invoice-issue-credit-note.spec.ts >> issues a partial credit note for a paid invoice with one item by crediting the customer balance and reducing the credit net amount - Location: src/manager/tests/e2e/invoice/invoice-issue-credit-note.spec.ts:28:7 # Error details ``` Test timeout of 120000ms exceeded. ``` ``` Error: page.waitForURL: Test timeout of 120000ms exceeded. =========================== logs =========================== waiting for navigation to "**/invoices/*" until "load" ============================================================ ``` # Page snapshot ```yaml - generic [active] [ref=f1e1]: - generic [ref=f1e6]: - navigation [ref=f1e7]: - generic [ref=f1e9]: - link [ref=f1e10] [cursor=pointer]: - /url: / - generic [ref=f1e11]: - generic [ref=f1e12]: KINNOVIS - generic [ref=f1e13]: Manager - button [ref=f1e15] [cursor=pointer] - list [ref=f1e19]: - generic [ref=f1e21]: Dashboard - link "Tasks" [ref=f1e23] [cursor=pointer]: - /url: /tasks - link "Facility maps" [ref=f1e30] [cursor=pointer]: - /url: /facility-map - generic [ref=f1e31]: 󰧾 - link "Analytics" [ref=f1e35] [cursor=pointer]: - /url: /dashboard - generic [ref=f1e36]: 󱖶 - generic [ref=f1e40]: Sales - link "Bookings" [ref=f1e42] [cursor=pointer]: - /url: /bookings - generic [ref=f1e43]: 󰇡 - link "Customers" [ref=f1e47] [cursor=pointer]: - /url: /customers - generic [ref=f1e48]: 󰀏 - link "Invoices" [ref=f1e52] [cursor=pointer]: - /url: /invoices - generic [ref=f1e53]: 󰷉 - link "Credit notes" [ref=f1e57] [cursor=pointer]: - /url: /credit-notes - link "Units" [ref=f1e64] [cursor=pointer]: - /url: /units - generic [ref=f1e65]: 󰍀 - generic [ref=f1e69]: Site management - link "Locations" [ref=f1e71] [cursor=pointer]: - /url: /locations - generic [ref=f1e72]: 󰟙 - link "Unit types" [ref=f1e76] [cursor=pointer]: - /url: /unit-types - generic [ref=f1e77]: 󰆧 - link "Protection Plans" [ref=f1e81] [cursor=pointer]: - /url: /insurances - generic [ref=f1e82]: 󰳌 - link "Deposits" [ref=f1e86] [cursor=pointer]: - /url: /deposits - generic [ref=f1e87]: 󱙆 - link "Products" [ref=f1e91] [cursor=pointer]: - /url: /products - generic [ref=f1e92]: 󰄑 - link "Discounts" [ref=f1e96] [cursor=pointer]: - /url: /discounts - generic [ref=f1e97]: 󰓼 - generic [ref=f1e101]: - option "Emails" [ref=f1e102] [cursor=pointer]: - generic [ref=f1e103]: 󰻨 - generic [ref=f1e107]: 󰅀 - text: 󱡰 󰁥 - generic [ref=f1e111]: Admin - link "Integrations" [ref=f1e113] [cursor=pointer]: - /url: /connected-apps - generic [ref=f1e114]: 󱘖 - link "User & Roles" [ref=f1e118] [cursor=pointer]: - /url: /users - generic [ref=f1e119]: 󰭘 - generic [ref=f1e123]: - option "Booking Portal" [ref=f1e124] [cursor=pointer]: - generic [ref=f1e125]: 󱃁 - generic [ref=f1e129]: 󰅀 - text: 󰖟 󰟙 - link "Public API" [ref=f1e133] [cursor=pointer]: - /url: /public-api - generic [ref=f1e134]: 󱂛 - generic [ref=f1e138]: Feedback - link "Voting Portal" [ref=f1e140] [cursor=pointer]: - /url: /voting-portal - generic [ref=f1e141]: 󰔔 - generic [ref=f1e147]: - button "AS Andreas Stadler andreas.stadler@storeroom.at" [ref=f1e150] [cursor=pointer]: - generic [ref=f1e151]: AS - generic [ref=f1e154]: - generic [ref=f1e155]: Andreas Stadler - generic "andreas.stadler@storeroom.at" [ref=f1e156] - generic [ref=f1e157]: 󰇙 - generic: 󰗊 󰅀 󰷖 󰍃 - button [ref=f1e158] [cursor=pointer]: - generic [ref=f1e159]: 󰋽 - main [ref=f1e161]: - generic [ref=f1e163]: - generic [ref=f1e165]: - generic [ref=f1e166]: - link "Invoices" [ref=f1e167] [cursor=pointer]: - /url: /invoices - generic [ref=f1e169]: 󰅂 - generic [ref=f1e170]: INV-2215429 - generic [ref=f1e171]: Paid - button [ref=f1e177] [cursor=pointer]: - generic [ref=f1e178]: - text: Actions - generic [ref=f1e179]: 󱨉 - generic: 󰇚 󱴆 󱳱 - generic [ref=f1e181]: - generic [ref=f1e183]: - heading "General" [level=3] [ref=f1e187] - table [ref=f1e190]: - rowgroup [ref=f1e191]: - row [ref=f1e192]: - rowheader "Location" [ref=f1e193] - cell "Vienna South" [ref=f1e194] - row [ref=f1e197]: - rowheader "Issue date" [ref=f1e198] - cell "10 Oct 2026" [ref=f1e199] - row [ref=f1e202]: - rowheader "Due date" [ref=f1e203] - cell "12 Oct 2026" [ref=f1e204] - row [ref=f1e207]: - rowheader "Total" [ref=f1e208] - cell "€720.00" [ref=f1e209] - row [ref=f1e212]: - rowheader "Amount due" [ref=f1e213] - cell "€0.00" [ref=f1e214] - row [ref=f1e217]: - rowheader "Period" [ref=f1e218] - cell "-" [ref=f1e219] - row [ref=f1e222]: - rowheader "Payment option" [ref=f1e223] - cell "Manual" [ref=f1e224] - row [ref=f1e227]: - rowheader "Payment link" [ref=f1e228] - cell "https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WUGZOcm85YVZ4dUVNWlI2UEJJdG52UWY3S3NiNUpOLDE4MjE0MDI0NA0200dJBzZuwO?s=ap" [ref=f1e229]: - generic [ref=f1e230]: - generic [ref=f1e231]: https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WUGZOcm85YVZ4dUVNWlI2UEJJdG52UWY3S3NiNUpOLDE4MjE0MDI0NA0200dJBzZuwO?s=ap - button [ref=f1e235] [cursor=pointer]: - generic [ref=f1e236]: 󰏌 - generic [ref=f1e239]: - heading "Customer details" [level=3] [ref=f1e243] - table [ref=f1e246]: - rowgroup [ref=f1e247]: - row [ref=f1e248]: - rowheader "Name" [ref=f1e249] - cell [ref=f1e250]: - link "Javonte Windler" [ref=f1e253] [cursor=pointer]: - /url: /customers/1902338107 - row [ref=f1e256]: - rowheader "Customer type" [ref=f1e257] - cell "Private" [ref=f1e258] - row [ref=f1e261]: - rowheader "Email" [ref=f1e262] - cell [ref=f1e263]: - link "timmothy80@yahoo.com" [ref=f1e266] [cursor=pointer]: - /url: mailto:timmothy80@yahoo.com - row [ref=f1e267]: - rowheader "Phone number" [ref=f1e268] - cell "+43 2073 476780" [ref=f1e269] - row [ref=f1e272]: - rowheader "Billing address" [ref=f1e273] - cell "Meghan Expressway 15362-2389 Concepcionport Austria" [ref=f1e274] - generic [ref=f1e278]: - heading "Payments" [level=3] [ref=f1e282] - generic [ref=f1e286]: - table [ref=f1e290]: - rowgroup [ref=f1e291]: - row [ref=f1e292]: - columnheader [ref=f1e293]: - button "Total" [ref=f1e294] [cursor=pointer]: - generic [ref=f1e297]: 󰁝 - columnheader [ref=f1e300]: - button "Status" [ref=f1e301] [cursor=pointer]: - generic [ref=f1e304]: 󰁝 - columnheader [ref=f1e307]: - button "Invoice no." [ref=f1e308] [cursor=pointer]: - generic [ref=f1e311]: 󰁝 - columnheader [ref=f1e314]: - button "Date" [ref=f1e315] [cursor=pointer]: - generic [ref=f1e318]: 󰁝 - columnheader [ref=f1e321]: - button "Payment method" [ref=f1e322] [cursor=pointer]: - generic [ref=f1e325]: 󰁝 - row [ref=f1e328]: - columnheader [ref=f1e329] - rowgroup [ref=f1e330]: - row [ref=f1e331]: - cell "€720.00" [ref=f1e332] - cell "Cancelled" [ref=f1e334] - cell "INV-2215429" [ref=f1e339] - cell "10 Oct 2026" [ref=f1e341] - cell [ref=f1e343] - row [ref=f1e344]: - cell "€720.00" [ref=f1e345] - cell "Succeeded" [ref=f1e347] - cell "INV-2215429" [ref=f1e352] - cell "10 Oct 2026" [ref=f1e354] - cell "Cash" [ref=f1e356] - generic [ref=f1e362]: - generic [ref=f1e363]: - generic [ref=f1e364]: "Items per page:" - combobox [ref=f1e367]: - generic [ref=f1e369] [cursor=pointer]: - generic [ref=f1e370]: "10" - combobox "Items per page:": "10" - generic [ref=f1e372]: 󰍝 - generic [ref=f1e374]: 1-2 of 2 - generic [ref=f1e375]: - button [disabled]: - generic: 󰘀 - button [disabled]: - generic: 󰅁 - button [disabled]: - generic: 󰅂 - button [disabled]: - generic: 󰘁 - generic [ref=f1e378]: - heading "Late Fees" [level=3] [ref=f1e383] - generic [ref=f1e387]: - table [ref=f1e391]: - rowgroup [ref=f1e392]: - row [ref=f1e393]: - columnheader "Invoice no." [ref=f1e394] - columnheader "Invoice note" [ref=f1e398] - columnheader "Created by" [ref=f1e402] - columnheader "Total" [ref=f1e406] - columnheader "Status" [ref=f1e410] - columnheader "Issue date" [ref=f1e414] - columnheader "Due date" [ref=f1e418] - row [ref=f1e422]: - columnheader [ref=f1e423] - rowgroup [ref=f1e424]: - row [ref=f1e425]: - cell "No data yet" [ref=f1e426] - generic [ref=f1e430]: - generic [ref=f1e431]: - generic [ref=f1e432]: "Items per page:" - combobox [ref=f1e435]: - generic [ref=f1e437] [cursor=pointer]: - generic [ref=f1e438]: "10" - combobox "Items per page:": "10" - generic [ref=f1e440]: 󰍝 - generic [ref=f1e442]: 0-0 of 0 - generic [ref=f1e443]: - button [disabled]: - generic: 󰘀 - button [disabled]: - generic: 󰅁 - button [disabled]: - generic: 󰅂 - button [disabled]: - generic: 󰘁 - generic: - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - tooltip - dialog: - generic [ref=f1e446]: - generic [ref=f1e447]: - generic [ref=f1e449]: - generic [ref=f1e450]: - button [ref=f1e451] [cursor=pointer]: - generic [ref=f1e452]: 󰅖 - heading "Issue Credit Note" [level=2] [ref=f1e455] - button "Save" [ref=f1e457] [cursor=pointer] - separator [ref=f1e459] - generic [ref=f1e461]: - group [ref=f1e462]: - heading "Invoice INV-2215429 Paid" [level=3] [ref=f1e464]: - generic [ref=f1e466]: - text: Invoice INV-2215429 - generic [ref=f1e467]: Paid - generic [ref=f1e471]: - generic [ref=f1e473]: - textbox "Reason *" [ref=f1e475]: Example reason! - generic: Reason * - alert [ref=f1e476] - group [ref=f1e478]: - heading "Items to credit" [level=3] [ref=f1e480] - generic [ref=f1e483]: - generic [ref=f1e484]: - table [ref=f1e486]: - rowgroup [ref=f1e487]: - row [ref=f1e488]: - columnheader "Description" [ref=f1e489] - columnheader "Credit QTY" [ref=f1e490] - columnheader "Price" [ref=f1e491] - columnheader "VAT" [ref=f1e492] - columnheader "Net credit amount" [ref=f1e493] - rowgroup [ref=f1e494]: - row [ref=f1e495]: - cell "Gorgeous Product ijUR2j Gorgeous Product ijUR2j" [ref=f1e496]: - generic [ref=f1e499]: - generic [ref=f1e501]: - generic [ref=f1e502]: 󰄲 - checkbox "Gorgeous Product ijUR2j" [checked] [ref=f1e503] [cursor=pointer] - generic [ref=f1e504] [cursor=pointer]: Gorgeous Product ijUR2j - cell [ref=f1e505]: - generic [ref=f1e506]: - combobox [ref=f1e508]: - generic [ref=f1e510]: - generic [ref=f1e511]: Custom - combobox [ref=f1e513]: Custom - button [ref=f1e515] [cursor=pointer]: 󰍝 - alert [ref=f1e516] - cell "€200.00" [ref=f1e518] - cell "20%" [ref=f1e519] - cell "10 €" [ref=f1e520]: - generic [ref=f1e521]: - generic [ref=f1e524]: - spinbutton [ref=f1e525]: "10" - generic [ref=f1e526]: € - alert [ref=f1e528] - alert [ref=f1e530] - generic [ref=f1e534]: - generic [ref=f1e535]: - generic [ref=f1e536]: Total excl.VAT - generic [ref=f1e537]: €10.00 - generic [ref=f1e538]: - generic [ref=f1e539]: VAT - generic [ref=f1e540]: €2.00 - generic [ref=f1e541]: - generic [ref=f1e542]: Total incl.VAT - generic [ref=f1e543]: €12.00 - group [ref=f1e545]: - heading "Select how to credit" [level=3] [ref=f1e547] - generic [ref=f1e551]: - generic [ref=f1e553]: - generic [ref=f1e555]: - radio "Refund to payment method" [ref=f1e556] - generic [ref=f1e557] [cursor=pointer]: Refund to payment method - generic [ref=f1e560]: 󰋽 - generic [ref=f1e563]: - radio "Refund to customer balance" [checked] [ref=f1e564] - generic [ref=f1e565] [cursor=pointer]: Refund to customer balance - generic [ref=f1e568]: 󰋽 - generic [ref=f1e571]: - radio "Credit outside of Stripe" [ref=f1e572] - generic [ref=f1e573] [cursor=pointer]: Credit outside of Stripe - generic [ref=f1e576]: 󰋽 - alert [ref=f1e578] - tooltip - tooltip - tooltip - tooltip ``` # Test source ```ts 1 | import { BaseDialog } from '@/manager/shared/base/BaseDialog'; 2 | import { InvoiceIssueCreditNoteGeneralFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteGeneralFieldSet'; 3 | import { InvoiceIssueCreditNoteItemsFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteItemsFieldSet'; 4 | import { InvoiceIssueCreditNoteOptionsFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteOptionsFieldSet'; 5 | import { InvoiceIssueCreditNoteData } from '@/manager/modules/invoice/invoice-types'; 6 | import { InvoiceDetailsPage } from '@/manager/modules/invoice/views/InvoiceDetailsPage'; 7 | import { InvoiceIssueCreditNoteConfirmDialog } from '@/manager/modules/invoice/views/InvoiceIssueCreditNoteConfirmDialog'; 8 | import { getDialogErrorsHost, getLoadingSpinnerHost, getSnackbarHost } from '@/manager/shared/utils/locator-utils'; 9 | import { Page } from '@playwright/test'; 10 | 11 | export class InvoiceIssueCreditNoteDialog extends BaseDialog { 12 | readonly generalFieldSet = new InvoiceIssueCreditNoteGeneralFieldSet(this.main); 13 | readonly itemsFieldSet = new InvoiceIssueCreditNoteItemsFieldSet(this.main); 14 | readonly optionsFieldSet = new InvoiceIssueCreditNoteOptionsFieldSet(this.main); 15 | readonly errors = getDialogErrorsHost(this.main); 16 | readonly loadingSpinner = getLoadingSpinnerHost(this.main); 17 | readonly snackbar = getSnackbarHost(this.host, 'Credit note successfully issued!'); 18 | 19 | constructor(host: Page) { 20 | super(host, 'invoice-issue-credit-note-dialog'); 21 | } 22 | 23 | async fill(data: InvoiceIssueCreditNoteData): Promise { 24 | await this.generalFieldSet.reasonTextAreaField.fill(data.reason); 25 | await this.itemsFieldSet.list.select(data.items); 26 | 27 | if (data.option != null) { 28 | await this.optionsFieldSet.radioGroup.check(data.option); 29 | } 30 | } 31 | 32 | async submit(): Promise { 33 | await this.loadingSpinner.waitFor({ state: 'hidden' }); 34 | await this.submitButton.click(); 35 | } 36 | 37 | async confirm(): Promise { 38 | const confirmDialog = new InvoiceIssueCreditNoteConfirmDialog(this.host); > 39 | await Promise.all([this.snackbar.waitFor(), this.host.waitForURL('**/invoices/*'), confirmDialog.submit()]); | ^ Error: page.waitForURL: Test timeout of 120000ms exceeded. 40 | return new InvoiceDetailsPage(this.host); 41 | } 42 | } 43 | ```