# 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 an open invoice with one item by reducing the credit net amount - Location: src/manager/tests/e2e/invoice/invoice-issue-credit-note.spec.ts:29:7 # Error details ``` Error: expect(locator).toHaveText(expected) failed Locator: locator('.v-dialog:has([data-test-id="invoice-issue-credit-note-dialog"]):has(.v-overlay__content:not(.dialog-bottom-transition-enter-active))').locator('fieldset:has(legend:has-text("Items to credit"))').getByTestId('totals-summary-section').getByTestId('total-excl-vat-value') Expected: "€10.00" Received: "€600.00" Timeout: 30000ms Call log: - Expect "toHaveText" with timeout 30000ms - waiting for locator('.v-dialog:has([data-test-id="invoice-issue-credit-note-dialog"]):has(.v-overlay__content:not(.dialog-bottom-transition-enter-active))').locator('fieldset:has(legend:has-text("Items to credit"))').getByTestId('totals-summary-section').getByTestId('total-excl-vat-value') 34 × locator resolved to
€600.00
- unexpected value "€600.00" ``` # 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]: - img [ref=e16] - list [ref=e19]: - generic [ref=e22]: Dashboard - link "Tasks" [ref=e23] [cursor=pointer]: - /url: /tasks - img [ref=e26] - generic [ref=e29]: Tasks - link "Facility maps" [ref=e30] [cursor=pointer]: - /url: /facility-map - generic [ref=e32]: 󰧾 - generic [ref=e34]: Facility maps - link "Analytics" [ref=e35] [cursor=pointer]: - /url: /dashboard - generic [ref=e37]: 󱖶 - generic [ref=e39]: Analytics - generic [ref=e41]: Sales - link "Bookings" [ref=e42] [cursor=pointer]: - /url: /bookings - generic [ref=e44]: 󰇡 - generic [ref=e46]: Bookings - link "Customers" [ref=e47] [cursor=pointer]: - /url: /customers - generic [ref=e49]: 󰀏 - generic [ref=e51]: Customers - link "Invoices" [ref=e52] [cursor=pointer]: - /url: /invoices - generic [ref=e54]: 󰷉 - generic [ref=e56]: Invoices - link "Credit notes" [ref=e57] [cursor=pointer]: - /url: /credit-notes - img [ref=e60] - generic [ref=e63]: Credit notes - link "Units" [ref=e64] [cursor=pointer]: - /url: /units - generic [ref=e66]: 󰍀 - generic [ref=e68]: Units - generic [ref=e70]: Site management - link "Locations" [ref=e71] [cursor=pointer]: - /url: /locations - generic [ref=e73]: 󰟙 - generic [ref=e75]: Locations - link "Unit types" [ref=e76] [cursor=pointer]: - /url: /unit-types - generic [ref=e78]: 󰆧 - generic [ref=e80]: Unit types - link "Protection Plans" [ref=e81] [cursor=pointer]: - /url: /insurances - generic [ref=e83]: 󰳌 - generic [ref=e85]: Protection Plans - link "Deposits" [ref=e86] [cursor=pointer]: - /url: /deposits - generic [ref=e88]: 󱙆 - generic [ref=e90]: Deposits - link "Products" [ref=e91] [cursor=pointer]: - /url: /products - generic [ref=e93]: 󰄑 - generic [ref=e95]: Products - link "Discounts" [ref=e96] [cursor=pointer]: - /url: /discounts - generic [ref=e98]: 󰓼 - generic [ref=e100]: Discounts - generic [ref=e101]: - option "Emails" [ref=e102] [cursor=pointer]: - generic [ref=e104]: 󰻨 - generic [ref=e106]: Emails - generic [ref=e110]: 󰅀 - text: 󱡰 󰁥 - generic [ref=e112]: Admin - link "Integrations" [ref=e113] [cursor=pointer]: - /url: /connected-apps - generic [ref=e115]: 󱘖 - generic [ref=e117]: Integrations - link "User & Roles" [ref=e118] [cursor=pointer]: - /url: /users - generic [ref=e120]: 󰭘 - generic [ref=e122]: User & Roles - generic [ref=e123]: - option "Booking Portal" [ref=e124] [cursor=pointer]: - generic [ref=e126]: 󱃁 - generic [ref=e128]: Booking Portal - generic [ref=e132]: 󰅀 - text: 󰖟 󰟙 - generic [ref=e133]: - option "JaneAI" [ref=e134] [cursor=pointer]: - generic [ref=e136]: 󱙺 - generic [ref=e138]: JaneAI - generic [ref=e142]: 󰅀 - text: 󱜹 - generic [ref=e144]: Feedback - link "Voting Portal" [ref=e145] [cursor=pointer]: - /url: /voting-portal - generic [ref=e147]: 󰔔 - generic [ref=e149]: Voting Portal - generic [ref=e152]: - button "AS Andreas Stadler andreas.stadler@storeroom.at" [ref=e155] [cursor=pointer]: - generic [ref=e158]: AS - generic [ref=e159]: - generic [ref=e160]: Andreas Stadler - generic "andreas.stadler@storeroom.at" [ref=e161] - generic [ref=e162]: 󰇙 - generic: - text: 󰗊 󰅀 - text: 󰷖 󰍃 - button [ref=e163] [cursor=pointer]: - generic [ref=e165]: 󰋽 - main [ref=e166]: - generic [ref=e168]: - generic [ref=e170]: - generic [ref=e171]: - link "Invoices" [ref=e172] [cursor=pointer]: - /url: /invoices - generic [ref=e173]: Invoices - generic [ref=e174]: 󰅂 - generic [ref=e175]: INV-2108663 - generic [ref=e180]: Open - button "Actions" [ref=e182] [cursor=pointer]: - generic [ref=e183]: - text: Actions - generic [ref=e184]: 󱨉 - generic: 󰇚 󱴆 󱳱 󱤒 󰆛 󰗡 󱈎 - generic [ref=e186]: - generic [ref=e188]: - heading "General" [level=3] [ref=e192] - table [ref=e195]: - rowgroup [ref=e196]: - row "Location Vienna South" [ref=e197]: - rowheader "Location" [ref=e198] - cell "Vienna South" [ref=e199]: - generic [ref=e201]: Vienna South - row "Issue date 20 Aug 2026" [ref=e202]: - rowheader "Issue date" [ref=e203] - cell "20 Aug 2026" [ref=e204]: - generic [ref=e206]: 20 Aug 2026 - row "Due date 22 Aug 2026" [ref=e207]: - rowheader "Due date" [ref=e208] - cell "22 Aug 2026" [ref=e209]: - generic [ref=e211]: 22 Aug 2026 - row "Total €720.00" [ref=e212]: - rowheader "Total" [ref=e213] - cell "€720.00" [ref=e214]: - generic [ref=e216]: €720.00 - row "Amount due €720.00" [ref=e217]: - rowheader "Amount due" [ref=e218] - cell "€720.00" [ref=e219]: - generic [ref=e221]: €720.00 - row "Period -" [ref=e222]: - rowheader "Period" [ref=e223] - cell "-" [ref=e224]: - generic [ref=e226]: "-" - row "Payment option Manual" [ref=e227]: - rowheader "Payment option" [ref=e228] - cell "Manual" [ref=e229]: - generic [ref=e231]: Manual - row "Payment link https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WNmNhd1MzVHJUcE9YZ2tGNzZOMzdzdkFqVEREeEFOLDE3Nzc0NzY0MQ02003UdUOVU4?s=ap" [ref=e232]: - rowheader "Payment link" [ref=e233] - cell "https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WNmNhd1MzVHJUcE9YZ2tGNzZOMzdzdkFqVEREeEFOLDE3Nzc0NzY0MQ02003UdUOVU4?s=ap" [ref=e234]: - generic [ref=e235]: - generic [ref=e238]: https://invoice.stripe.com/i/acct_1MeJfDB0vsavZFES/test_YWNjdF8xTWVKZkRCMHZzYXZaRkVTLF9WNmNhd1MzVHJUcE9YZ2tGNzZOMzdzdkFqVEREeEFOLDE3Nzc0NzY0MQ02003UdUOVU4?s=ap - button [ref=e240] [cursor=pointer]: - generic [ref=e242]: 󰏌 - generic [ref=e244]: - heading "Customer details" [level=3] [ref=e248] - table [ref=e251]: - rowgroup [ref=e252]: - row "Name Raymond Schmeler" [ref=e253]: - rowheader "Name" [ref=e254] - cell "Raymond Schmeler" [ref=e255]: - link "Raymond Schmeler" [ref=e258] [cursor=pointer]: - /url: /customers/53809381 - generic [ref=e260]: Raymond Schmeler - row "Customer type Private" [ref=e261]: - rowheader "Customer type" [ref=e262] - cell "Private" [ref=e263]: - generic [ref=e265]: Private - row "Email angie8@yahoo.com" [ref=e266]: - rowheader "Email" [ref=e267] - cell "angie8@yahoo.com" [ref=e268]: - link "angie8@yahoo.com" [ref=e271] [cursor=pointer]: - /url: mailto:angie8@yahoo.com - row "Phone number +43 50 0172 4097" [ref=e272]: - rowheader "Phone number" [ref=e273] - cell "+43 50 0172 4097" [ref=e274]: - generic [ref=e276]: +43 50 0172 4097 - row "Billing address Wunsch Ranch 85166-7364 Stratford Austria" [ref=e277]: - rowheader "Billing address" [ref=e278] - cell "Wunsch Ranch 85166-7364 Stratford Austria" [ref=e279]: - generic [ref=e281]: Wunsch Ranch 85166-7364 Stratford Austria - generic [ref=e283]: - heading "Payments" [level=3] [ref=e287] - generic [ref=e291]: - table [ref=e295]: - rowgroup [ref=e296]: - row "Total Status Invoice no. Date Payment method" [ref=e297]: - columnheader "Total" [ref=e298]: - button "Total" [ref=e299] [cursor=pointer]: - generic [ref=e301]: Total - generic [ref=e304]: 󰁝 - columnheader "Status" [ref=e305]: - button "Status" [ref=e306] [cursor=pointer]: - generic [ref=e308]: Status - generic [ref=e311]: 󰁝 - columnheader "Invoice no." [ref=e312]: - button "Invoice no." [ref=e313] [cursor=pointer]: - generic [ref=e315]: Invoice no. - generic [ref=e318]: 󰁝 - columnheader "Date" [ref=e319]: - button "Date" [ref=e320] [cursor=pointer]: - generic [ref=e322]: Date - generic [ref=e325]: 󰁝 - columnheader "Payment method" [ref=e326]: - button "Payment method" [ref=e327] [cursor=pointer]: - generic [ref=e329]: Payment method - generic [ref=e332]: 󰁝 - row [ref=e333]: - columnheader [ref=e334] - rowgroup [ref=e335]: - row "€720.00 Not paid yet INV-2108663 20 Aug 2026" [ref=e336]: - cell "€720.00" [ref=e337]: - generic [ref=e338]: €720.00 - cell "Not paid yet" [ref=e339]: - generic [ref=e343]: Not paid yet - cell "INV-2108663" [ref=e344]: - generic [ref=e345]: INV-2108663 - cell "20 Aug 2026" [ref=e346]: - generic [ref=e347]: 20 Aug 2026 - cell [ref=e348] - generic [ref=e351]: - generic [ref=e352]: - generic [ref=e353]: "Items per page:" - combobox [ref=e356]: - generic [ref=e358] [cursor=pointer]: - generic [ref=e360]: "10" - combobox "Items per page:": "10" - generic [ref=e362]: 󰍝 - generic [ref=e363]: 1-1 of 1 - generic [ref=e364]: - button [disabled]: - generic: - generic: 󰘀 - button [disabled]: - generic: - generic: 󰅁 - button [disabled]: - generic: - generic: 󰅂 - button [disabled]: - generic: - generic: 󰘁 - generic [ref=e367]: - heading "Late Fees" [level=3] [ref=e372] - generic [ref=e376]: - table [ref=e380]: - rowgroup [ref=e381]: - row "Invoice no. Invoice note Created by Total Status Issue date Due date" [ref=e382]: - columnheader "Invoice no." [ref=e383]: - generic [ref=e386]: Invoice no. - columnheader "Invoice note" [ref=e387]: - generic [ref=e390]: Invoice note - columnheader "Created by" [ref=e391]: - generic [ref=e394]: Created by - columnheader "Total" [ref=e395]: - generic [ref=e398]: Total - columnheader "Status" [ref=e399]: - generic [ref=e402]: Status - columnheader "Issue date" [ref=e403]: - generic [ref=e406]: Issue date - columnheader "Due date" [ref=e407]: - generic [ref=e410]: Due date - row [ref=e411]: - columnheader [ref=e412] - rowgroup [ref=e413]: - row "No data yet" [ref=e414]: - cell "No data yet" [ref=e415]: - generic [ref=e416]: No data yet - generic [ref=e419]: - generic [ref=e420]: - generic [ref=e421]: "Items per page:" - combobox [ref=e424]: - generic [ref=e426] [cursor=pointer]: - generic [ref=e428]: "10" - combobox "Items per page:": "10" - generic [ref=e430]: 󰍝 - generic [ref=e431]: 0-0 of 0 - generic [ref=e432]: - button [disabled]: - generic: - generic: 󰘀 - button [disabled]: - generic: - generic: 󰅁 - button [disabled]: - generic: - generic: 󰅂 - button [disabled]: - generic: - 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]: - generic [ref=e436]: - generic [ref=e438]: - generic [ref=e439]: - button [ref=e440] [cursor=pointer]: - generic [ref=e442]: 󰅖 - heading "Issue Credit Note" [level=2] [ref=e444] - button "Save" [ref=e446] [cursor=pointer]: - generic [ref=e447]: Save - separator [ref=e448] - generic [ref=e450]: - group "Invoice INV-2108663 Open" [ref=e451]: - heading "Invoice INV-2108663 Open" [level=3] [ref=e453]: - generic [ref=e455]: - text: Invoice INV-2108663 - generic [ref=e457]: Open - generic [ref=e460]: - generic [ref=e462]: - textbox "Reason *" [ref=e464]: Example reason! - generic: - generic: Reason * - alert [ref=e465] - group "Items to credit" [ref=e467]: - heading "Items to credit" [level=3] [ref=e469]: - generic [ref=e471]: Items to credit - generic [ref=e472]: - generic [ref=e473]: - table [ref=e475]: - rowgroup [ref=e476]: - row "Description Credit QTY Price VAT Net credit amount" [ref=e477]: - columnheader "Description" [ref=e478] - columnheader "Credit QTY" [ref=e479] - columnheader "Price" [ref=e480] - columnheader "VAT" [ref=e481] - columnheader "Net credit amount" [ref=e482] - rowgroup [ref=e483]: - row "Generic Product KbeVkL Generic Product KbeVkL €200.00 20% 600 €" [ref=e484]: - cell "Generic Product KbeVkL Generic Product KbeVkL" [ref=e485]: - generic [ref=e488]: - generic [ref=e490]: - generic [ref=e491]: 󰄲 - checkbox "Generic Product KbeVkL" [checked] [ref=e492] [cursor=pointer] - generic [ref=e493] [cursor=pointer]: Generic Product KbeVkL - cell [ref=e494]: - generic [ref=e495]: - combobox [ref=e497]: - generic [ref=e499]: - generic [ref=e501]: "3" - combobox [ref=e502] - button [ref=e504] [cursor=pointer]: 󰍝 - alert [ref=e505] - cell "€200.00" [ref=e507] - cell "20%" [ref=e508] - cell "600 €" [ref=e509]: - generic [ref=e510]: - generic [ref=e513]: - spinbutton [active] [ref=e514]: "600" - generic [ref=e516]: € - alert [ref=e517] - alert [ref=e519] - generic [ref=e523]: - generic [ref=e524]: - generic [ref=e525]: Total excl.VAT - generic [ref=e526]: €600.00 - generic [ref=e527]: - generic [ref=e528]: VAT - generic [ref=e529]: €120.00 - generic [ref=e530]: - generic [ref=e531]: Total incl.VAT - generic [ref=e532]: €720.00 - generic [ref=e534]: - generic [ref=e536]: 󰋽 - generic [ref=e537]: The customer will receive an email with the credit note + an adjusted invoice attached. The invoice will be adjusted with the credited amount. The payment link will be updated for the correct amount as well. - tooltip ``` # Test source ```ts 1 | import { expect, Locator } from '@playwright/test'; 2 | 3 | export async function expectMultiLocatorToHaveText(locator: Locator, text: string[] | undefined): Promise { 4 | if (!text) { 5 | await expectLocatorToBeEmpty(locator); 6 | return; 7 | } 8 | 9 | const expectedValue = RegExp(text.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')); 10 | 11 | for (const element of await locator.all()) { 12 | await expectSingleLocatorToHaveText(element, expectedValue); 13 | } 14 | } 15 | 16 | export async function expectSingleLocatorToHaveText( 17 | locator: Locator, 18 | text: string | RegExp | undefined 19 | ): Promise { 20 | text > 21 | ? await expect(locator).toHaveText(text, { ignoreCase: true, useInnerText: true }) | ^ Error: expect(locator).toHaveText(expected) failed 22 | : await expectLocatorToBeEmpty(locator); 23 | } 24 | 25 | export async function expectLocatorToBeEmpty(locator: Locator): Promise { 26 | await expect(locator).toHaveText(/^(\s*-?\s*)$/); 27 | } 28 | ```