# 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-charge-customer.spec.ts >> charges the customer of an open invoice with sepa - Location: src/manager/tests/e2e/invoice/invoice-charge-customer.spec.ts:22:7 # Error details ``` Test timeout of 120000ms exceeded. ``` ``` Error: locator.waitFor: Test timeout of 120000ms exceeded. Call log: - waiting for locator('.v-snackbar').filter({ hasText: 'Charged customer successfully' }) to be visible ``` # Page snapshot ```yaml - generic [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: 󱡰 󰁥 - generic [ref=e111]: Admin - link "Integrations" [ref=e113] [cursor=pointer]: - /url: /connected-apps - generic [ref=e114]: 󱘖 - link "User & Roles" [ref=e118] [cursor=pointer]: - /url: /users - generic [ref=e119]: 󰭘 - generic [ref=e123]: - option "Booking Portal" [ref=e124] [cursor=pointer]: - generic [ref=e125]: 󱃁 - generic [ref=e129]: 󰅀 - text: 󰖟 󰟙 - link "Public API" [ref=e133] [cursor=pointer]: - /url: /public-api - generic [ref=e134]: 󱂛 - generic [ref=e138]: Feedback - link "Voting Portal" [ref=e140] [cursor=pointer]: - /url: /voting-portal - generic [ref=e141]: 󰔔 - generic [ref=e147]: - button "AS Andreas Stadler andreas.stadler@storeroom.at" [ref=e150] [cursor=pointer]: - generic [ref=e151]: AS - generic [ref=e154]: - generic [ref=e155]: Andreas Stadler - generic "andreas.stadler@storeroom.at" [ref=e156] - generic [ref=e157]: 󰇙 - generic: 󰗊 󰅀 󰷖 󰍃 - button [ref=e158] [cursor=pointer]: - generic [ref=e159]: 󰋽 - main [ref=e161]: - generic [ref=e163]: - generic [ref=e165]: - generic [ref=e166]: - link "Invoices" [ref=e167] [cursor=pointer]: - /url: /invoices - generic [ref=e169]: 󰅂 - generic [ref=e170]: INV-2212232 - generic [ref=e171]: Open - button [ref=e177] [cursor=pointer]: - generic [ref=e178]: - text: Actions - generic [ref=e179]: 󱨉 - generic: 󰇚 󱴆 󱳱 󱤒 󰆛 󰗡 󱈎 - generic [ref=e181]: - generic [ref=e183]: - heading "General" [level=3] [ref=e187] - table [ref=e190]: - rowgroup [ref=e191]: - row [ref=e192]: - rowheader "Location" [ref=e193] - cell "Vienna South" [ref=e194] - row [ref=e197]: - rowheader "Issue date" [ref=e198] - cell "9 Oct 2026" [ref=e199] - row [ref=e202]: - rowheader "Due date" [ref=e203] - cell "11 Oct 2026" [ref=e204] - row [ref=e207]: - rowheader "Total" [ref=e208] - cell "€1,672.80" [ref=e209] - row [ref=e212]: - rowheader "Amount due" [ref=e213] - cell "€1,672.80" [ref=e214] - row [ref=e217]: - rowheader "Period" [ref=e218] - cell "-" [ref=e219] - row [ref=e222]: - rowheader "Payment option" [ref=e223] - cell "Manual" [ref=e224] - row [ref=e227]: - rowheader "Payment link" [ref=e228] - cell "https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WUEkzUk9WSVdYdkdqRktyb2hqenRiMG1QZDRDUEZiLDE4MjA1MzQzNQ0200v7KYjcIf?s=ap" [ref=e229]: - generic [ref=e230]: - generic [ref=e231]: https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WUEkzUk9WSVdYdkdqRktyb2hqenRiMG1QZDRDUEZiLDE4MjA1MzQzNQ0200v7KYjcIf?s=ap - button [ref=e235] [cursor=pointer]: - generic [ref=e236]: 󰏌 - generic [ref=e239]: - heading "Customer details" [level=3] [ref=e243] - table [ref=e246]: - rowgroup [ref=e247]: - row [ref=e248]: - rowheader "Name" [ref=e249] - cell [ref=e250]: - link "Mikel Gutkowski" [ref=e253] [cursor=pointer]: - /url: /customers/580143309 - row [ref=e256]: - rowheader "Customer type" [ref=e257] - cell "Private" [ref=e258] - row [ref=e261]: - rowheader "Email" [ref=e262] - cell [ref=e263]: - link "paulette_veum16@hotmail.com" [ref=e266] [cursor=pointer]: - /url: mailto:paulette_veum16@hotmail.com - row [ref=e267]: - rowheader "Phone number" [ref=e268] - cell "+43 855 7359511" [ref=e269] - row [ref=e272]: - rowheader "Billing address" [ref=e273] - cell "Commercial Street 68392 Gleasonborough Austria" [ref=e274] - generic [ref=e278]: - heading "Payments" [level=3] [ref=e282] - generic [ref=e286]: - table [ref=e290]: - rowgroup [ref=e291]: - row [ref=e292]: - columnheader [ref=e293]: - button "Total" [ref=e294] [cursor=pointer]: - generic [ref=e297]: 󰁝 - columnheader [ref=e300]: - button "Status" [ref=e301] [cursor=pointer]: - generic [ref=e304]: 󰁝 - columnheader [ref=e307]: - button "Invoice no." [ref=e308] [cursor=pointer]: - generic [ref=e311]: 󰁝 - columnheader [ref=e314]: - button "Date" [ref=e315] [cursor=pointer]: - generic [ref=e318]: 󰁝 - columnheader [ref=e321]: - button "Payment method" [ref=e322] [cursor=pointer]: - generic [ref=e325]: 󰁝 - row [ref=e328]: - columnheader [ref=e329] - rowgroup [ref=e330]: - row [ref=e331]: - cell "€1,672.80" [ref=e332] - cell "Not paid yet" [ref=e334] - cell "INV-2212232" [ref=e339] - cell "9 Oct 2026" [ref=e341] - cell "SEPA via Stripe SEPA via Stripe •••• 3201" [ref=e343]: - generic [ref=e345]: - img "SEPA via Stripe" [ref=e346] - generic [ref=e347]: SEPA via Stripe - generic [ref=e348]: •••• 3201 - generic [ref=e351]: - generic [ref=e352]: - generic [ref=e353]: "Items per page:" - combobox [ref=e356]: - generic [ref=e358] [cursor=pointer]: - generic [ref=e359]: "10" - combobox "Items per page:": "10" - generic [ref=e361]: 󰍝 - generic [ref=e363]: 1-1 of 1 - generic [ref=e364]: - button [disabled]: - generic: 󰘀 - button [disabled]: - generic: 󰅁 - button [disabled]: - generic: 󰅂 - button [disabled]: - generic: 󰘁 - generic [ref=e367]: - heading "Late Fees" [level=3] [ref=e372] - generic [ref=e376]: - table [ref=e380]: - rowgroup [ref=e381]: - row [ref=e382]: - columnheader "Invoice no." [ref=e383] - columnheader "Invoice note" [ref=e387] - columnheader "Created by" [ref=e391] - columnheader "Total" [ref=e395] - columnheader "Status" [ref=e399] - columnheader "Issue date" [ref=e403] - columnheader "Due date" [ref=e407] - row [ref=e411]: - columnheader [ref=e412] - rowgroup [ref=e413]: - row [ref=e414]: - cell "No data yet" [ref=e415] - generic [ref=e419]: - generic [ref=e420]: - generic [ref=e421]: "Items per page:" - combobox [ref=e424]: - generic [ref=e426] [cursor=pointer]: - generic [ref=e427]: "10" - combobox "Items per page:": "10" - generic [ref=e429]: 󰍝 - generic [ref=e431]: 0-0 of 0 - generic [ref=e432]: - 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 - tooltip - dialog: - generic [ref=e435]: - heading "Charge customer for invoice" [level=3] [ref=e439] - generic [ref=e443]: - generic [ref=e444]: - generic [ref=e445]: Amount due - generic [ref=e446]: €1,672.80 - generic [ref=e448]: - generic [ref=e449]: Existing payment method - generic [ref=e452]: - generic [ref=e456]: - button "SEPA via Stripe IBAN •••• 3201" [ref=e460] [cursor=pointer]: - generic [ref=e461]: - generic [ref=e462]: 󰄲 - generic [ref=e463]: - generic [ref=e464]: - img "SEPA via Stripe" [ref=e465] - generic [ref=e466]: - generic [ref=e467]: IBAN - generic [ref=e468]: •••• 3201 - button [ref=e469]: - generic [ref=e470]: 󰩺 - alert [ref=e472] - button "Add payment method" [ref=e474] [cursor=pointer] - contentinfo [ref=e477]: - generic [ref=e480]: - button "Cancel" [ref=e481] [cursor=pointer] - button "Charge" [active] [ref=e483] [cursor=pointer] - tooltip ``` # Test source ```ts 1 | import { BaseDialog } from '@/manager/shared/base/BaseDialog'; 2 | import { PaymentMethodAddForm } from '@/manager/modules/ui/payment-method/components/PaymentMethodAddForm'; 3 | import { getSnackbarHost } from '@/manager/shared/utils/locator-utils'; 4 | import { PaymentMethod } from '@/shared/modules/payment-method/payment-method-types'; 5 | import { Page } from '@playwright/test'; 6 | 7 | export class InvoiceChargeCustomerDialog extends BaseDialog { 8 | readonly paymentMethodForm = new PaymentMethodAddForm(this.main); 9 | readonly snackbar = getSnackbarHost(this.host, 'Charged customer successfully'); 10 | readonly errorSnackbar = getSnackbarHost(this.host, 'Validation failed'); 11 | 12 | constructor(host: Page) { 13 | super(host, 'invoice-charge-customer-dialog'); 14 | } 15 | 16 | async charge(method: PaymentMethod): Promise { 17 | await this.fill(method); > 18 | await Promise.all([this.snackbar.waitFor(), this.submit()]); | ^ Error: locator.waitFor: Test timeout of 120000ms exceeded. 19 | } 20 | 21 | async fill(method: PaymentMethod): Promise { 22 | await this.paymentMethodForm.select(method); 23 | } 24 | 25 | async submit(): Promise { 26 | await this.submitButton.click(); 27 | } 28 | } 29 | ```