1- import { expect , BrowserContext , Page } from '@playwright/test' ;
1+ import { expect , BrowserContext , Page , Locator } from '@playwright/test' ;
22import Cookie from 'js-cookie' ;
33import { Config } from '../src/ui/types' ;
44
@@ -8,7 +8,7 @@ export class OrejimePage {
88 public readonly context : BrowserContext
99 ) { }
1010
11- async load ( config : Partial < Config > , scripts : string ) {
11+ async load ( config : Partial < Config > , body : string ) {
1212 await this . page . route ( '/' , async ( route ) => {
1313 await route . fulfill ( {
1414 body : `
@@ -21,11 +21,21 @@ export class OrejimePage {
2121 </head>
2222
2323 <body>
24+ ${ body }
25+
26+ <!--
27+ A dummy focusable element at the end of the page
28+ so there is always something to reach when
29+ navigating with the keyboard.
30+ Otherwise, some tests would fail in Firefox.
31+ @see https://github.com/microsoft/playwright/issues/32269
32+ -->
33+ <div tabindex="0"></div>
34+
2435 <script>
2536 window.orejimeConfig = ${ JSON . stringify ( config ) }
2637 </script>
2738 <script src="orejime-standard-en.js"></script>
28- ${ scripts }
2939 </body>
3040 </html>
3141 `
@@ -36,61 +46,69 @@ export class OrejimePage {
3646 }
3747
3848 get banner ( ) {
39- return this . page . locator ( '.orejime-Banner' ) ;
49+ return this . locator ( '.orejime-Banner' ) ;
4050 }
4151
4252 get learnMoreBannerButton ( ) {
43- return this . page . locator ( '.orejime-Banner-learnMoreButton' ) ;
53+ return this . locator ( '.orejime-Banner-learnMoreButton' ) ;
4454 }
4555
4656 get firstFocusableElementFromBanner ( ) {
47- return this . page . locator ( '.orejime-Banner :is(a, button)' ) . first ( ) ;
57+ return this . locator ( '.orejime-Banner :is(a, button)' ) . first ( ) ;
4858 }
4959
5060 get modal ( ) {
51- return this . page . locator ( '.orejime-Modal' ) ;
61+ return this . locator ( '.orejime-Modal' ) ;
5262 }
5363
54- purposeCheckbox ( purposeId : string ) {
55- return this . page . locator ( `#orejime-purpose-${ purposeId } ` ) ;
64+ get contextualNotice ( ) {
65+ return this . locator ( '.orejime-ContextualNotice' ) ;
66+ }
67+
68+ get contextualNoticePlaceholder ( ) {
69+ return this . locator ( '.orejime-ContextualNotice-placeholder' ) ;
70+ }
71+
72+ locator ( selector : string ) {
73+ return this . page . locator ( selector ) ;
5674 }
5775
58- async focusNext ( ) {
59- await this . page . keyboard . press ( 'Tab' ) ;
76+ purposeCheckbox ( purposeId : string ) {
77+ return this . locator ( `#orejime-purpose- ${ purposeId } ` ) ;
6078 }
6179
6280 async acceptAllFromBanner ( ) {
63- await this . page . locator ( '.orejime-Banner-saveButton' ) . click ( ) ;
81+ await this . locator ( '.orejime-Banner-saveButton' ) . click ( ) ;
6482 }
6583
6684 async declineAllFromBanner ( ) {
67- await this . page . locator ( '.orejime-Banner-declineButton' ) . click ( ) ;
85+ await this . locator ( '.orejime-Banner-declineButton' ) . click ( ) ;
6886 }
6987
7088 async openModalFromBanner ( ) {
7189 await this . learnMoreBannerButton . click ( ) ;
7290 }
7391
7492 async enableAllFromModal ( ) {
75- await this . page . locator ( '.orejime-PurposeToggles-enableAll' ) . click ( ) ;
93+ await this . locator ( '.orejime-PurposeToggles-enableAll' ) . click ( ) ;
7694 }
7795
7896 async disableAllFromModal ( ) {
79- await this . page . locator ( '.orejime-PurposeToggles-disableAll' ) . click ( ) ;
97+ await this . locator ( '.orejime-PurposeToggles-disableAll' ) . click ( ) ;
8098 }
8199
82100 async saveFromModal ( ) {
83- await this . page . locator ( '.orejime-Modal-saveButton' ) . click ( ) ;
101+ await this . locator ( '.orejime-Modal-saveButton' ) . click ( ) ;
84102 }
85103
86104 async closeModalByClickingButton ( ) {
87- await this . page . locator ( '.orejime-Modal-closeButton' ) . click ( ) ;
105+ await this . locator ( '.orejime-Modal-closeButton' ) . click ( ) ;
88106 }
89107
90108 async closeModalByClickingOutside ( ) {
91109 // We're clicking in a corner to avoid clicking on the
92110 // modal itself, which has no effect.
93- await this . page . locator ( '.orejime-ModalOverlay' ) . click ( {
111+ await this . locator ( '.orejime-ModalOverlay' ) . click ( {
94112 position : {
95113 x : 1 ,
96114 y : 1
@@ -102,12 +120,8 @@ export class OrejimePage {
102120 await this . page . keyboard . press ( 'Escape' ) ;
103121 }
104122
105- async expectElement ( selector : string ) {
106- await expect ( this . page . locator ( selector ) ) . toBeAttached ( ) ;
107- }
108-
109- async expectMissingElement ( selector : string ) {
110- await expect ( this . page . locator ( selector ) ) . not . toBeAttached ( ) ;
123+ async acceptContextualNotice ( ) {
124+ await this . locator ( '.orejime-ContextualNotice-button' ) . click ( ) ;
111125 }
112126
113127 async expectConsents ( consents : Record < string , unknown > ) {
@@ -120,4 +134,13 @@ export class OrejimePage {
120134 const { value} = cookies . find ( ( cookie ) => cookie . name === name ) ! ;
121135 return JSON . parse ( Cookie . converter . read ( value , name ) ) ;
122136 }
137+
138+ // In specific conditions, browser events can get queued
139+ // up and won't be fired until some interaction with the
140+ // page.
141+ // We're using a dummy click to trigger queued events.
142+ // @see https://github.com/microsoft/playwright/issues/979
143+ emptyEventQueue ( ) {
144+ return this . page . mouse . click ( 0 , 0 ) ;
145+ }
123146}
0 commit comments