# 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 multiple items by crediting outside of stripe and reducing the credit quantity - 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=e1]: - generic [ref=e6]: - navigation [ref=e7]: - generic [ref=e9]: - link [ref=e10] [cursor=pointer]: - /url: / - generic [ref=e11]: - generic [ref=e12]: KINNOVIS - generic [ref=e13]: Manager - button [ref=e15] [cursor=pointer] - list [ref=e19]: - generic [ref=e21]: Dashboard - link "Tasks" [ref=e23] [cursor=pointer]: - /url: /tasks - link "Facility maps" [ref=e30] [cursor=pointer]: - /url: /facility-map - generic [ref=e31]: 󰧾 - link "Analytics" [ref=e35] [cursor=pointer]: - /url: /dashboard - generic [ref=e36]: 󱖶 - generic [ref=e40]: Sales - link "Bookings" [ref=e42] [cursor=pointer]: - /url: /bookings - generic [ref=e43]: 󰇡 - link "Customers" [ref=e47] [cursor=pointer]: - /url: /customers - generic [ref=e48]: 󰀏 - link "Invoices" [ref=e52] [cursor=pointer]: - /url: /invoices - generic [ref=e53]: 󰷉 - link "Credit notes" [ref=e57] [cursor=pointer]: - /url: /credit-notes - link "Units" [ref=e64] [cursor=pointer]: - /url: /units - generic [ref=e65]: 󰍀 - generic [ref=e69]: Site management - link "Locations" [ref=e71] [cursor=pointer]: - /url: /locations - generic [ref=e72]: 󰟙 - link "Unit types" [ref=e76] [cursor=pointer]: - /url: /unit-types - generic [ref=e77]: 󰆧 - link "Protection Plans" [ref=e81] [cursor=pointer]: - /url: /insurances - generic [ref=e82]: 󰳌 - link "Deposits" [ref=e86] [cursor=pointer]: - /url: /deposits - generic [ref=e87]: 󱙆 - link "Products" [ref=e91] [cursor=pointer]: - /url: /products - generic [ref=e92]: 󰄑 - link "Discounts" [ref=e96] [cursor=pointer]: - /url: /discounts - generic [ref=e97]: 󰓼 - generic [ref=e101]: - option "Emails" [ref=e102] [cursor=pointer]: - generic [ref=e103]: 󰻨 - generic [ref=e107]: 󰅀 - text: 󱡰 󰁥 - link "Document templates" [ref=e111] [cursor=pointer]: - /url: /document-templates - generic [ref=e112]: 󰷉 - generic [ref=e116]: Admin - link "Integrations" [ref=e118] [cursor=pointer]: - /url: /connected-apps - generic [ref=e119]: 󱘖 - link "User & Roles" [ref=e123] [cursor=pointer]: - /url: /users - generic [ref=e124]: 󰭘 - generic [ref=e128]: - option "Booking Portal" [ref=e129] [cursor=pointer]: - generic [ref=e130]: 󱃁 - generic [ref=e134]: 󰅀 - text: 󰖟 󰟙 - generic [ref=e138]: - option "JaneAI" [ref=e139] [cursor=pointer]: - generic [ref=e140]: 󱙺 - generic [ref=e144]: 󰅀 - text: 󱜹 - generic [ref=e148]: Feedback - link "Voting Portal" [ref=e150] [cursor=pointer]: - /url: /voting-portal - generic [ref=e151]: 󰔔 - generic [ref=e157]: - button "AS Andreas Stadler andreas.stadler@storeroom.at" [ref=e160] [cursor=pointer]: - generic [ref=e161]: AS - generic [ref=e164]: - generic [ref=e165]: Andreas Stadler - generic "andreas.stadler@storeroom.at" [ref=e166] - generic [ref=e167]: 󰇙 - generic: 󰗊 󰅀 󰷖 󰍃 - button [ref=e168] [cursor=pointer]: - generic [ref=e169]: 󰋽 - main [ref=e171]: - generic [ref=e173]: - generic [ref=e175]: - generic [ref=e176]: - link "Invoices" [ref=e177] [cursor=pointer]: - /url: /invoices - generic [ref=e179]: 󰅂 - generic [ref=e180]: INV-2122191 - generic [ref=e181]: Paid - button [ref=e187] [cursor=pointer]: - generic [ref=e188]: - text: Actions - generic [ref=e189]: 󱨉 - generic: 󰇚 󱴆 󱳱 - generic [ref=e191]: - generic [ref=e193]: - heading "General" [level=3] [ref=e197] - table [ref=e200]: - rowgroup [ref=e201]: - row [ref=e202]: - rowheader "Location" [ref=e203] - cell "Vienna South" [ref=e204] - row [ref=e207]: - rowheader "Issue date" [ref=e208] - cell "28 Aug 2026" [ref=e209] - row [ref=e212]: - rowheader "Due date" [ref=e213] - cell "30 Aug 2026" [ref=e214] - row [ref=e217]: - rowheader "Total" [ref=e218] - cell "€840.00" [ref=e219] - row [ref=e222]: - rowheader "Amount due" [ref=e223] - cell "€0.00" [ref=e224] - row [ref=e227]: - rowheader "Period" [ref=e228] - cell "-" [ref=e229] - row [ref=e232]: - rowheader "Payment option" [ref=e233] - cell "Manual" [ref=e234] - row [ref=e237]: - rowheader "Payment link" [ref=e238] - cell "https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WOVduQlNDRGZ0VkVBMWEzelpSd2R6TEhUSnBhQlhCLDE3ODQxODA0Ng0200Y9DVf7nH?s=ap" [ref=e239]: - generic [ref=e240]: - generic [ref=e241]: https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WOVduQlNDRGZ0VkVBMWEzelpSd2R6TEhUSnBhQlhCLDE3ODQxODA0Ng0200Y9DVf7nH?s=ap - button [ref=e245] [cursor=pointer]: - generic [ref=e246]: 󰏌 - generic [ref=e249]: - heading "Customer details" [level=3] [ref=e253] - table [ref=e256]: - rowgroup [ref=e257]: - row [ref=e258]: - rowheader "Name" [ref=e259] - cell [ref=e260]: - link "Jaquelin Nienow" [ref=e263] [cursor=pointer]: - /url: /customers/204936538 - row [ref=e266]: - rowheader "Customer type" [ref=e267] - cell "Private" [ref=e268] - row [ref=e271]: - rowheader "Email" [ref=e272] - cell [ref=e273]: - link "darrin71@hotmail.com" [ref=e276] [cursor=pointer]: - /url: mailto:darrin71@hotmail.com - row [ref=e277]: - rowheader "Phone number" [ref=e278] - cell "+43 5278 958437" [ref=e279] - row [ref=e282]: - rowheader "Billing address" [ref=e283] - cell "The Maltings 87816 Port Emmet Austria" [ref=e284] - generic [ref=e288]: - heading "Payments" [level=3] [ref=e292] - generic [ref=e296]: - table [ref=e300]: - rowgroup [ref=e301]: - row [ref=e302]: - columnheader [ref=e303]: - button "Total" [ref=e304] [cursor=pointer]: - generic [ref=e307]: 󰁝 - columnheader [ref=e310]: - button "Status" [ref=e311] [cursor=pointer]: - generic [ref=e314]: 󰁝 - columnheader [ref=e317]: - button "Invoice no." [ref=e318] [cursor=pointer]: - generic [ref=e321]: 󰁝 - columnheader [ref=e324]: - button "Date" [ref=e325] [cursor=pointer]: - generic [ref=e328]: 󰁝 - columnheader [ref=e331]: - button "Payment method" [ref=e332] [cursor=pointer]: - generic [ref=e335]: 󰁝 - row [ref=e338]: - columnheader [ref=e339] - rowgroup [ref=e340]: - row [ref=e341]: - cell "€840.00" [ref=e342] - cell "Cancelled" [ref=e344] - cell "INV-2122191" [ref=e349] - cell "28 Aug 2026" [ref=e351] - cell [ref=e353] - row [ref=e354]: - cell "€840.00" [ref=e355] - cell "Succeeded" [ref=e357] - cell "INV-2122191" [ref=e362] - cell "28 Aug 2026" [ref=e364] - cell "Cash" [ref=e366] - generic [ref=e372]: - generic [ref=e373]: - generic [ref=e374]: "Items per page:" - combobox [ref=e377]: - generic [ref=e379] [cursor=pointer]: - generic [ref=e380]: "10" - combobox "Items per page:": "10" - generic [ref=e382]: 󰍝 - generic [ref=e384]: 1-2 of 2 - generic [ref=e385]: - button [disabled]: - generic: 󰘀 - button [disabled]: - generic: 󰅁 - button [disabled]: - generic: 󰅂 - button [disabled]: - generic: 󰘁 - generic [ref=e388]: - heading "Late Fees" [level=3] [ref=e393] - generic [ref=e397]: - table [ref=e401]: - rowgroup [ref=e402]: - row [ref=e403]: - columnheader "Invoice no." [ref=e404] - columnheader "Invoice note" [ref=e408] - columnheader "Created by" [ref=e412] - columnheader "Total" [ref=e416] - columnheader "Status" [ref=e420] - columnheader "Issue date" [ref=e424] - columnheader "Due date" [ref=e428] - row [ref=e432]: - columnheader [ref=e433] - rowgroup [ref=e434]: - row [ref=e435]: - cell "No data yet" [ref=e436] - generic [ref=e440]: - generic [ref=e441]: - generic [ref=e442]: "Items per page:" - combobox [ref=e445]: - generic [ref=e447] [cursor=pointer]: - generic [ref=e448]: "10" - combobox "Items per page:": "10" - generic [ref=e450]: 󰍝 - generic [ref=e452]: 0-0 of 0 - generic [ref=e453]: - 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 - tooltip - dialog: - generic [ref=e456]: - generic [ref=e457]: - generic [ref=e459]: - generic [ref=e460]: - button [ref=e461] [cursor=pointer]: - generic [ref=e462]: 󰅖 - heading "Issue Credit Note" [level=2] [ref=e465] - button "Save" [ref=e467] [cursor=pointer] - separator [ref=e469] - generic [ref=e471]: - group [ref=e472]: - heading "Invoice INV-2122191 Paid" [level=3] [ref=e474]: - generic [ref=e476]: - text: Invoice INV-2122191 - generic [ref=e477]: Paid - generic [ref=e481]: - generic [ref=e483]: - textbox "Reason *" [ref=e485]: Example reason! - generic: Reason * - alert [ref=e486] - group [ref=e488]: - heading "Items to credit" [level=3] [ref=e490] - generic [ref=e493]: - generic [ref=e494]: - table [ref=e496]: - rowgroup [ref=e497]: - row [ref=e498]: - columnheader "Description" [ref=e499] - columnheader "Credit QTY" [ref=e500] - columnheader "Price" [ref=e501] - columnheader "VAT" [ref=e502] - columnheader "Net credit amount" [ref=e503] - rowgroup [ref=e504]: - row [ref=e505]: - cell "Ergonomic Product f0Koxk Ergonomic Product f0Koxk" [ref=e506]: - generic [ref=e509]: - generic [ref=e511]: - generic [ref=e512]: 󰄲 - checkbox "Ergonomic Product f0Koxk" [checked] [ref=e513] [cursor=pointer] - generic [ref=e514] [cursor=pointer]: Ergonomic Product f0Koxk - cell [ref=e515]: - generic [ref=e516]: - combobox [ref=e518]: - generic [ref=e520]: - generic [ref=e521]: "1" - combobox [ref=e523] - button [ref=e525] [cursor=pointer]: 󰍝 - alert [ref=e526] - cell "€100.00" [ref=e528] - cell "20%" [ref=e529] - cell "100 €" [ref=e530]: - generic [ref=e531]: - generic [ref=e534]: - spinbutton [ref=e535]: "100" - generic [ref=e536]: € - alert [ref=e538] - row [ref=e540]: - cell "Modern Product VuI4Yr Modern Product VuI4Yr" [ref=e541]: - generic [ref=e544]: - generic [ref=e546]: - generic [ref=e547]: 󰄲 - checkbox "Modern Product VuI4Yr" [checked] [ref=e548] [cursor=pointer] - generic [ref=e549] [cursor=pointer]: Modern Product VuI4Yr - cell [ref=e550]: - generic [ref=e551]: - combobox [ref=e553]: - generic [ref=e555]: - generic [ref=e556]: "2" - combobox [ref=e558] - button [ref=e560] [cursor=pointer]: 󰍝 - alert [ref=e561] - cell "€200.00" [ref=e563] - cell "20%" [ref=e564] - cell "400 €" [ref=e565]: - generic [ref=e566]: - generic [ref=e569]: - spinbutton [ref=e570]: "400" - generic [ref=e571]: € - alert [ref=e573] - alert [ref=e575] - generic [ref=e579]: - generic [ref=e580]: - generic [ref=e581]: Total excl.VAT - generic [ref=e582]: €500.00 - generic [ref=e583]: - generic [ref=e584]: VAT - generic [ref=e585]: €100.00 - generic [ref=e586]: - generic [ref=e587]: Total incl.VAT - generic [ref=e588]: €600.00 - group [ref=e590]: - heading "Select how to credit" [level=3] [ref=e592] - generic [ref=e596]: - generic [ref=e598]: - generic [ref=e600]: - radio "Refund to payment method" [ref=e601] - generic [ref=e602] [cursor=pointer]: Refund to payment method - generic [ref=e605]: 󰋽 - generic [ref=e608]: - radio "Refund to customer balance" [ref=e609] - generic [ref=e610] [cursor=pointer]: Refund to customer balance - generic [ref=e613]: 󰋽 - generic [ref=e616]: - radio "Credit outside of Stripe" [checked] [ref=e617] - generic [ref=e618] [cursor=pointer]: Credit outside of Stripe - generic [ref=e621]: 󰋽 - generic [ref=e623]: - generic [ref=e624]: 󰋽 - generic [ref=e627]: - text: The existing payment details for a bank transfer are not up-to-date, contact the customer to get up-to-date payment details for the manual bank transfer. - link [ref=e628] [cursor=pointer]: - /url: /customers/204936538 - generic [ref=e629]: - text: Customer details - generic [ref=e630]: 󰏌 - alert [ref=e631] - 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 | ```