# 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-bulk-mark-as-paid.spec.ts >> marks multiple selected invoices as paid at once
- Location: src/manager/tests/e2e/invoice/invoice-bulk-mark-as-paid.spec.ts:145:5

# Error details

```
Test timeout of 120000ms exceeded.
```

```
Error: locator.click: Test timeout of 120000ms exceeded.
Call log:
  - waiting for getByTestId('app-page').getByTestId('app-page-content').locator('.ui-data-grid').locator('[data-test-id=ui-data-grid-table]:not(.disabled):not(.loading):not(.fetching)').locator('button[data-test-id="invoice-bulk-mark-as-paid-action"]')

```

# 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: 󰖟 󰟙
        - generic [ref=e133]:
          - option "JaneAI" [ref=e134] [cursor=pointer]:
            - generic [ref=e135]: 󱙺
            - generic [ref=e139]: 󰅀
          - text: 󱜹
        - generic [ref=e143]: Feedback
        - link "Voting Portal" [ref=e145] [cursor=pointer]:
          - /url: /voting-portal
          - generic [ref=e146]: 󰔔
      - generic [ref=e152]:
        - button "AS Andreas Stadler andreas.stadler@storeroom.at" [ref=e155] [cursor=pointer]:
          - generic [ref=e156]: AS
          - generic [ref=e159]:
            - generic [ref=e160]: Andreas Stadler
            - generic "andreas.stadler@storeroom.at" [ref=e161]
          - generic [ref=e162]: 󰇙
          - generic: 󰗊 󰅀 󰷖 󰍃
        - button [ref=e163] [cursor=pointer]:
          - generic [ref=e164]: 󰋽
    - main [ref=e166]:
      - generic [ref=e168]:
        - generic [ref=e170]:
          - generic [ref=e171]: Invoices
          - generic [ref=e174]:
            - link [ref=e175] [cursor=pointer]:
              - /url: /invoices/create
              - generic [ref=e176]:
                - generic [ref=e177]: 󰐕
                - text: Create Invoice
            - button [ref=e178] [cursor=pointer]:
              - generic [ref=e179]: 󰍝
        - generic [ref=e184]:
          - generic [ref=e186]:
            - button [ref=e187] [cursor=pointer]:
              - generic [ref=e188]:
                - heading "Filters" [level=3] [ref=e191]
                - generic [ref=e193]:
                  - button [ref=e195]:
                    - generic [ref=e196]:
                      - generic [ref=e197]: 󰑐
                      - text: Reset filters
                  - generic [ref=e199]: 󰅀
            - generic [ref=e207]:
              - generic [ref=e212]:
                - generic [ref=e213]: 󰍉
                - textbox "Search" [ref=e216]: Wayne BodeBEkpZX
                - button "Clear Search" [ref=e218] [cursor=pointer]: 󰅙
                - generic: Search
              - combobox [ref=e222]:
                - generic [ref=e223]:
                  - generic: Location
                  - combobox "Location" [ref=e225]
                - button [ref=e227] [cursor=pointer]: 󰍝
              - combobox [ref=e231]:
                - generic [ref=e232]:
                  - generic: Status
                  - combobox "Status" [ref=e234]
                - button [ref=e236] [cursor=pointer]: 󰍝
              - combobox [ref=e240]:
                - generic [ref=e241]:
                  - generic: Payment option
                  - combobox "Payment option" [ref=e243]
                - button [ref=e245] [cursor=pointer]: 󰍝
              - combobox [ref=e249]:
                - generic [ref=e250]:
                  - generic: Type
                  - combobox "Type" [ref=e252]
                - button [ref=e254] [cursor=pointer]: 󰍝
              - generic [ref=e259]:
                - generic [ref=e260]: 󰸗
                - generic [ref=e262]:
                  - generic: Created at
                  - textbox "Created at" [ref=e263]:
                    - generic: 󰅁 󰍝 󰅂 󰅁 󰍝 󰅂
                - text: 󰅙
          - generic [ref=e265]:
            - generic [ref=e267]:
              - generic [ref=e269]:
                - generic [ref=e271]:
                  - generic [ref=e272]: 2 selected
                  - generic [ref=e277]:
                    - button "Deselect all" [ref=e282] [cursor=pointer]:
                      - generic [ref=e283]: 󰅖
                    - button "Select all" [ref=e290] [cursor=pointer]:
                      - generic [ref=e291]: 󰄬
                - generic [ref=e294]:
                  - button "Mark as paid" [ref=e297] [cursor=pointer]:
                    - generic [ref=e298]: 󰗡
                  - button "SEPA XML actions" [disabled] [ref=e303]:
                    - generic [ref=e304]: 󱨉
                    - generic: 󰗡 󰅚 󰗖
                  - generic [ref=e309]:
                    - button [ref=e310] [cursor=pointer]
                    - generic: 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲 󰄲
              - table [ref=e316]:
                - rowgroup [ref=e317]:
                  - row [ref=e318]:
                    - columnheader [ref=e319]:
                      - generic [ref=e320]:
                        - checkbox [ref=e321]
                        - generic [ref=e322] [cursor=pointer]: 󰄱
                    - columnheader [ref=e324]:
                      - button "Number" [ref=e325] [cursor=pointer]:
                        - generic [ref=e328]: 󰁝
                    - columnheader [ref=e331]:
                      - button "Location" [ref=e332] [cursor=pointer]:
                        - generic [ref=e335]: 󰁝
                    - columnheader [ref=e338]:
                      - button "Status" [ref=e339] [cursor=pointer]:
                        - generic [ref=e342]: 󰁝
                    - columnheader [ref=e345]:
                      - button "Payment option" [ref=e346] [cursor=pointer]:
                        - generic [ref=e349]: 󰁝
                    - columnheader [ref=e352]:
                      - button "Due date" [ref=e353] [cursor=pointer]:
                        - generic [ref=e356]: 󰁝
                    - columnheader [ref=e359]:
                      - button "Customer" [ref=e360] [cursor=pointer]:
                        - generic [ref=e363]: 󰁝
                    - columnheader [ref=e366]:
                      - button "Unit" [ref=e367] [cursor=pointer]:
                        - generic [ref=e370]: 󰁝
                    - columnheader "Discount" [ref=e373]
                    - columnheader [ref=e377]:
                      - button "Total (incl. VAT)" [ref=e378] [cursor=pointer]:
                        - generic [ref=e379]:
                          - generic [ref=e380]: Total (incl. VAT)
                          - generic [ref=e381]: 󰋽
                        - generic [ref=e383]: 󰁝
                    - columnheader [ref=e386]:
                      - button "Amount due" [ref=e387] [cursor=pointer]:
                        - generic [ref=e390]: 󰁝
                    - columnheader [ref=e393]:
                      - button "Issue date" [ref=e394] [cursor=pointer]:
                        - generic [ref=e397]: 󰁝
                    - columnheader "Actions" [ref=e400]
                  - row [ref=e404]:
                    - columnheader [ref=e405]
                - rowgroup [ref=e406]:
                  - row [ref=e407]:
                    - cell [ref=e408]:
                      - generic [ref=e409]:
                        - checkbox [checked] [ref=e410]
                        - generic [ref=e411] [cursor=pointer]: 󰄲
                    - cell [ref=e413]:
                      - link "INV-2110605" [ref=e414] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e416]:
                      - link "Vienna South" [ref=e417] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e419]:
                      - link "Open" [ref=e420] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e425]:
                      - link "Manual" [ref=e426] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e428]:
                      - link "23 Aug 2026" [ref=e429] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e431]:
                      - link "Wayne BodeBEkpZX" [ref=e432] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e435]:
                      - link [ref=e436] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell "-" [ref=e437]
                    - cell [ref=e439]:
                      - link "€129.60" [ref=e440] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e442]:
                      - link "€129.60" [ref=e443] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e445]:
                      - link "21 Aug 2026" [ref=e446] [cursor=pointer]:
                        - /url: /invoices/1175351722
                    - cell [ref=e448]:
                      - button [ref=e451] [cursor=pointer]:
                        - generic [ref=e452]: 󰇘
                        - generic: 󰇚 󰯝
                  - row [ref=e454]:
                    - cell [ref=e455]:
                      - generic [ref=e456]:
                        - checkbox [checked] [active] [ref=e457]
                        - generic [ref=e458] [cursor=pointer]: 󰄲
                    - cell [ref=e460]:
                      - link "INV-2110607" [ref=e461] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e463]:
                      - link "Vienna South" [ref=e464] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e466]:
                      - link "Open" [ref=e467] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e472]:
                      - link "Manual" [ref=e473] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e475]:
                      - link "23 Aug 2026" [ref=e476] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e478]:
                      - link "Wayne BodeBEkpZX" [ref=e479] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e482]:
                      - link [ref=e483] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell "-" [ref=e484]
                    - cell [ref=e486]:
                      - link "€129.60" [ref=e487] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e489]:
                      - link "€129.60" [ref=e490] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e492]:
                      - link "21 Aug 2026" [ref=e493] [cursor=pointer]:
                        - /url: /invoices/876303184
                    - cell [ref=e495]:
                      - button [ref=e498] [cursor=pointer]:
                        - generic [ref=e499]: 󰇘
                        - generic: 󰇚 󰯝
                  - row [ref=e501]:
                    - cell [ref=e502]:
                      - generic [ref=e503]:
                        - checkbox [ref=e504]
                        - generic [ref=e505] [cursor=pointer]: 󰄱
                    - cell [ref=e507]:
                      - link "INV-2110603" [ref=e508] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e510]:
                      - link "Vienna South" [ref=e511] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e513]:
                      - link "Open" [ref=e514] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e519]:
                      - link "Manual" [ref=e520] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e522]:
                      - link "23 Aug 2026" [ref=e523] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e525]:
                      - link "Wayne BodeBEkpZX" [ref=e526] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e529]:
                      - link [ref=e530] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell "-" [ref=e531]
                    - cell [ref=e533]:
                      - link "€129.60" [ref=e534] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e536]:
                      - link "€129.60" [ref=e537] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e539]:
                      - link "21 Aug 2026" [ref=e540] [cursor=pointer]:
                        - /url: /invoices/80298941
                    - cell [ref=e542]:
                      - button [ref=e545] [cursor=pointer]:
                        - generic [ref=e546]: 󰇘
                        - generic: 󰇚 󰯝
            - generic [ref=e550]:
              - generic [ref=e551]:
                - generic [ref=e552]: "Items per page:"
                - combobox [ref=e555]:
                  - generic [ref=e557] [cursor=pointer]:
                    - generic [ref=e558]: "10"
                    - combobox "Items per page:": "10"
                  - generic [ref=e560]: 󰍝
              - generic [ref=e562]: 1-3 of 3
              - generic [ref=e563]:
                - 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
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
    - tooltip
```

# Test source

```ts
  1  | import { BasePage } from '@/manager/shared/base/BasePage';
  2  | import { InvoiceBulkMarkAsPaidDialog } from '@/manager/modules/invoice/views/InvoiceBulkMarkAsPaidDialog';
  3  | import { InvoiceCreateDialog } from '@/manager/modules/invoice/views/InvoiceCreateDialog';
  4  | import { InvoiceDetailsPage } from '@/manager/modules/invoice/views/InvoiceDetailsPage';
  5  | import { DataTable } from '@/manager/modules/ui/data-table/components/DataTable';
  6  | import { DebouncedTextField } from '@/manager/shared/components/DebouncedTextField';
  7  | import { MultiAutocomplete } from '@/manager/shared/components/MultiAutocomplete';
  8  | import { RangeDatePicker } from '@/manager/shared/components/RangeDatePicker';
  9  | import { getFilterHost } from '@/manager/shared/utils/locator-utils';
  10 | 
  11 | export class InvoiceListPage extends BasePage {
  12 |   readonly actionButton = this.header.getByTestId('invoice-list-action-button');
  13 |   readonly searchTextField = new DebouncedTextField(getFilterHost(this.body, 'Search'));
  14 |   readonly locationAutocomplete = new MultiAutocomplete(getFilterHost(this.body, 'Location'));
  15 |   readonly statusAutocomplete = new MultiAutocomplete(getFilterHost(this.body, 'Status'));
  16 |   readonly createdAtDatePicker = new RangeDatePicker(getFilterHost(this.body, 'Created at'));
  17 |   readonly dataTable = new DataTable(this.body);
  18 |   readonly bulkMarkAsPaidActionButton = this.dataTable.rowSelector.getAction('invoice-bulk-mark-as-paid-action');
  19 | 
  20 |   async goto(): Promise<void> {
  21 |     await this.host.goto('/invoices');
  22 |   }
  23 | 
  24 |   selectInvoices(indexes: number | number[]): Promise<void> {
  25 |     return this.dataTable.rowSelector.select(indexes);
  26 |   }
  27 | 
  28 |   async openInvoiceBulkMarkAsPaidDialog(): Promise<InvoiceBulkMarkAsPaidDialog> {
> 29 |     await this.bulkMarkAsPaidActionButton.click();
     |                                           ^ Error: locator.click: Test timeout of 120000ms exceeded.
  30 |     return new InvoiceBulkMarkAsPaidDialog(this.host);
  31 |   }
  32 | 
  33 |   async openInvoiceCreateDialog(): Promise<InvoiceCreateDialog> {
  34 |     await this.dataTable.waitForLoading();
  35 |     await Promise.all([this.host.waitForURL('/invoices/create'), this.actionButton.click()]);
  36 |     return new InvoiceCreateDialog(this.host);
  37 |   }
  38 | 
  39 |   async goToInvoiceDetailsPage(index: number): Promise<InvoiceDetailsPage> {
  40 |     await Promise.all([this.host.waitForURL('**/invoices/*'), this.dataTable.clickRow(index)]);
  41 |     return new InvoiceDetailsPage(this.host);
  42 |   }
  43 | }
  44 | 
```