1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
16- import { test , expect , Page } from '@playwright/test' ;
16+ import {
17+ test ,
18+ expect ,
19+ Page ,
20+ type BrowserContext ,
21+ type TestInfo ,
22+ } from '@playwright/test' ;
23+ import {
24+ navigateToInsights ,
25+ getPanel ,
26+ selectDateRange ,
27+ openDateRangePicker ,
28+ closeDateRangePicker ,
29+ visitCatalogEntity ,
30+ runTemplate ,
31+ visitDocs ,
32+ performSearch ,
33+ waitForDataFlush ,
34+ verifyTableEntries ,
35+ verifyPanelContainsTexts ,
36+ switchToLocale ,
37+ } from './utils/insightsHelpers' ;
38+ import { runAccessibilityTests } from './utils/accessibility.js' ;
39+ import {
40+ InsightsMessages ,
41+ getTranslations ,
42+ replaceTemplate ,
43+ } from './utils/translations.js' ;
1744
1845test . describe . configure ( { mode : 'serial' } ) ;
1946
2047let page : Page ;
21-
22- async function navigate ( link : string ) {
23- const navLink = page . locator ( `nav a:has-text("${ link } ")` ) . first ( ) ;
24- await navLink . waitFor ( { state : 'visible' } ) ;
25- await navLink . click ( ) ;
26- }
48+ let context : BrowserContext ;
49+ let translations : InsightsMessages ;
2750
2851test . beforeAll ( async ( { browser } ) => {
29- page = await browser . newPage ( ) ;
52+ context = await browser . newContext ( ) ;
53+ page = await context . newPage ( ) ;
54+ const currentLocale = await page . evaluate (
55+ ( ) => globalThis . navigator . language ,
56+ ) ;
3057 await page . goto ( '/' ) ;
3158 await page . getByRole ( 'button' , { name : 'Enter' } ) . click ( ) ;
3259
33- // give the insights plugin some time to crunch the new login
34- await new Promise ( res => setTimeout ( res , 8000 ) ) ;
60+ await switchToLocale ( page , currentLocale ) ;
61+ translations = getTranslations ( currentLocale ) ;
62+
63+ await waitForDataFlush ( ) ;
3564} ) ;
3665
37- test ( 'Insights is available' , async ( ) => {
38- await navigate ( 'Adoption Insights' ) ;
66+ test . afterAll ( async ( ) => {
67+ await context . close ( ) ;
68+ } ) ;
3969
40- const heading = page . getByRole ( 'heading' , { name : 'Insights' } ) . first ( ) ;
70+ test ( 'Insights is available' , async ( {
71+ browser : _browser ,
72+ } , testInfo : TestInfo ) => {
73+ await navigateToInsights ( page , translations . header . title ) ;
74+
75+ const heading = page
76+ . getByRole ( 'heading' , { name : translations . header . title } )
77+ . first ( ) ;
4178
4279 expect ( page . url ( ) ) . toContain ( '/adoption-insights' ) ;
4380 await expect ( heading ) . toBeVisible ( ) ;
81+
82+ await runAccessibilityTests ( page , testInfo ) ;
4483} ) ;
4584
4685test ( 'Select date range' , async ( ) => {
47- const dateRanges = [ 'Today' , 'Last week' , 'Last month' , 'Last year' ] ;
48- await page . getByText ( 'Last 28 days' ) . click ( ) ;
86+ const dateRanges = [
87+ translations . header . dateRange . today ,
88+ translations . header . dateRange . lastWeek ,
89+ translations . header . dateRange . lastMonth ,
90+ translations . header . dateRange . lastYear ,
91+ ] ;
92+ await page . getByText ( translations . header . dateRange . defaultLabel ) . click ( ) ;
4993 for ( const range of dateRanges ) {
5094 await expect ( page . getByRole ( 'option' , { name : range } ) ) . toBeVisible ( ) ;
5195 }
52- const dateRange = page . getByRole ( 'option' , { name : `Date range...` } ) ;
53- await expect ( dateRange ) . toBeVisible ( ) ;
54- await dateRange . click ( ) ;
96+ await openDateRangePicker ( page , translations . header . dateRange . dateRange ) ;
5597
5698 const datePicker = page . locator ( '.v5-MuiPaper-root' , {
5799 hasText : 'Start date' ,
58100 } ) ;
59101 await expect ( datePicker ) . toBeVisible ( ) ;
60- await datePicker . getByRole ( 'button' , { name : 'Cancel' } ) . click ( ) ;
102+ await closeDateRangePicker ( page , translations . header . dateRange . cancel ) ;
61103 await expect ( datePicker ) . not . toBeVisible ( ) ;
62104
63- await page . getByRole ( 'option' , { name : 'Today' } ) . click ( ) ;
105+ await selectDateRange ( page , translations . header . dateRange . today ) ;
64106} ) ;
65107
66108test ( 'Active users panel shows 1 visitor' , async ( ) => {
67- const panel = page . locator ( '.v5-MuiPaper-root' , { hasText : 'Active users' } ) ;
109+ const panel = getPanel ( page , translations . activeUsers . title ) ;
68110 await expect ( panel . locator ( '.recharts-surface' ) ) . toBeVisible ( ) ;
111+ const averageTextContent = replaceTemplate (
112+ translations . activeUsers . averageText ,
113+ {
114+ count : 1 ,
115+ period : translations . activeUsers . hour ,
116+ } ,
117+ ) ;
118+ const averageText = `${ translations . activeUsers . averagePrefix } ${ averageTextContent } ${ translations . activeUsers . averageSuffix } ` ;
69119 await expect ( panel ) . toMatchAriaSnapshot ( `
70- - heading "Active users" [level=5]
71- - button "Export CSV"
72- - paragraph: Average peak active user count was 1 per hour for this period.
120+ - heading "${ translations . activeUsers . title } " [level=5]
121+ - button "${ translations . common . exportCSV } "
122+ - paragraph: ${ averageText }
123+ - paragraph: ${ translations . activeUsers . legend . returningUsers }
124+ - paragraph: ${ translations . activeUsers . legend . newUsers }
73125 ` ) ;
74126} ) ;
75127
76128test ( 'Total number of users panel shows 1 visitor of 100' , async ( ) => {
77- const panel = page . locator ( '.v5-MuiPaper-root' , {
78- hasText : 'Total number of users' ,
79- } ) ;
129+ const panel = getPanel ( page , translations . users . title ) ;
80130 await expect ( panel . locator ( '.recharts-surface' ) ) . toBeVisible ( ) ;
131+ const ofTotalText = `1 ${ replaceTemplate ( translations . users . ofTotal , {
132+ total : 100 ,
133+ } ) } `;
81134 await expect ( panel ) . toMatchAriaSnapshot ( `
82- - heading "Total number of users" [level=5]
135+ - heading "${ translations . users . title } " [level=5]
83136 - img:
84- - text: 1 of 100
137+ - text: ${ ofTotalText }
85138 - list:
86- - listitem: Logged-in users
87- - listitem: Licensed (not logged in)
139+ - listitem: ${ translations . users . loggedInUsers }
140+ - listitem: ${ translations . users . licensedNotLoggedIn }
88141 - heading "1%" [level=1]
89- - paragraph: have logged in
142+ - paragraph: ${ translations . users . haveLoggedIn }
90143 ` ) ;
91144} ) ;
92145
93146test ( 'Top plugins shows catalog' , async ( ) => {
94- await navigate ( 'Adoption Insights' ) ;
95- const panel = page . locator ( '.v5-MuiPaper-root' , { hasText : 'All plugins' } ) ;
147+ await navigateToInsights ( page , translations . header . title ) ;
148+ const pluginRegex = new RegExp (
149+ `${ translations . plugins . allTitle } |${ replaceTemplate (
150+ translations . plugins . topNTitle ,
151+ { count : '\\d' } ,
152+ ) } `,
153+ ) ;
154+
155+ const panel = page . locator ( '.v5-MuiPaper-root' , {
156+ hasText : pluginRegex ,
157+ } ) ;
96158 await expect ( panel ) . toMatchAriaSnapshot ( `
97- - heading "All plugins" [level=5]
98159 - table:
99160 - rowgroup:
100161 - row :
101- - columnheader "Name "
102- - columnheader "Trend "
103- - columnheader "Views "
162+ - columnheader "${ translations . table . headers . name } "
163+ - columnheader "${ translations . table . headers . trend } "
164+ - columnheader "${ translations . table . headers . views } "
104165 - rowgroup:
105166 - row :
106167 - cell "catalog"
@@ -109,94 +170,107 @@ test('Top plugins shows catalog', async () => {
109170
110171test ( 'Rest of the panels have no data' , async ( ) => {
111172 const titles = [
112- 'Top templates' ,
113- 'Top catalog entities' ,
114- 'Top TechDocs' ,
115- 'Top searches' ,
173+ translations . templates . title ,
174+ translations . catalogEntities . title ,
175+ translations . techDocs . title ,
176+ translations . searches . title ,
116177 ] ;
117178 for ( const title of titles ) {
118- const panel = page . locator ( '.v5-MuiPaper-root' , { hasText : title } ) ;
119- await expect ( panel ) . toContainText ( 'No results for this date range.' ) ;
179+ const panel = getPanel ( page , title ) ;
180+ await expect ( panel ) . toContainText ( translations . common . noResults ) ;
120181 }
121182} ) ;
122183
123184test . describe ( ( ) => {
124185 test . beforeAll ( async ( ) => {
125186 // visit a catalog entity
126- await navigate ( 'home' ) ;
127- await page . getByRole ( 'link' , { name : 'example-website' } ) . click ( ) ;
128- await page
129- . getByRole ( 'heading' , { name : 'example-website' } )
130- . waitFor ( { state : 'visible' } ) ;
187+ await visitCatalogEntity ( page , 'example-website' ) ;
131188
132189 // run a template
133- await navigate ( 'create...' ) ;
134- await page . getByTestId ( 'template-card-actions--create' ) . click ( ) ;
135- await page . getByRole ( 'textbox' ) . fill ( 'reallyUniqueName' ) ;
136- await page . getByRole ( 'button' , { name : 'next' } ) . click ( ) ;
137- await page . getByRole ( 'textbox' ) . first ( ) . fill ( 'orgthatdoesntexist' ) ;
138- await page . getByRole ( 'textbox' ) . last ( ) . fill ( 'repothatdoesntexist' ) ;
139- await page . getByRole ( 'button' , { name : 'review' } ) . click ( ) ;
140- await page . getByRole ( 'button' , { name : 'create' } ) . click ( ) ;
141- await page
142- . getByText ( 'Run of Example Node.js Template' )
143- . waitFor ( { state : 'visible' } ) ;
190+ await runTemplate (
191+ page ,
192+ 'reallyUniqueName' ,
193+ 'orgthatdoesntexist' ,
194+ 'repothatdoesntexist' ,
195+ ) ;
144196
145197 // visit the docs
146- await navigate ( 'docs' ) ;
147- await page . getByText ( 'No documents to show' ) . waitFor ( { state : 'visible' } ) ;
198+ await visitDocs ( page ) ;
148199
149200 // do a search
150- await page . getByRole ( 'button' , { name : 'search' } ) . click ( ) ;
151- await page . getByRole ( 'textbox' ) . fill ( 'searching for something' ) ;
152-
153- const noSearchResults = page . getByRole ( 'heading' , {
154- name : 'Sorry, no results were found' ,
155- } ) ;
156- await noSearchResults . waitFor ( { state : 'visible' } ) ;
157- await page . getByRole ( 'button' , { name : 'close' } ) . click ( ) ;
201+ await performSearch ( page , 'searching for something' ) ;
158202
159203 // wait for the flush interval to be sure
160- await new Promise ( res => setTimeout ( res , 8000 ) ) ;
204+ await waitForDataFlush ( ) ;
161205
162- await navigate ( 'Adoption Insights' ) ;
163- await page . getByText ( 'Last 28 days' ) . click ( ) ;
164- await page . getByRole ( 'option' , { name : `Today` } ) . click ( ) ;
206+ await navigateToInsights ( page ) ;
207+ await page . getByText ( translations . header . dateRange . defaultLabel ) . click ( ) ;
208+ await selectDateRange ( page , translations . header . dateRange . today ) ;
165209 } ) ;
166210
167211 test ( 'Visited component shows up in top catalog entities' , async ( ) => {
168- const panel = page . locator ( '.v5-MuiPaper-root' , {
169- hasText : 'All catalog entities' ,
170- } ) ;
171- const entries = panel . locator ( 'tbody' ) . locator ( 'tr' ) ;
172- await expect ( entries ) . toHaveCount ( 1 ) ;
173- await expect ( entries ) . toContainText ( 'example-website' ) ;
212+ const panel = getPanel ( page , translations . catalogEntities . allTitle ) ;
213+ await expect ( panel ) . toContainText ( translations . filter . selectKind ) ;
214+ await panel . getByLabel ( translations . filter . selectKind ) . click ( ) ;
215+ await expect ( page . getByRole ( 'listbox' ) ) . toMatchAriaSnapshot ( `
216+ - listbox "${ translations . filter . selectKind } ":
217+ - option "${ translations . filter . all } "
218+ - option "Component"
219+ ` ) ;
220+
221+ await verifyPanelContainsTexts ( panel , [
222+ translations . table . headers . name ,
223+ translations . table . headers . kind ,
224+ translations . table . headers . lastUsed ,
225+ translations . table . headers . views ,
226+ ] ) ;
227+
228+ await verifyTableEntries ( panel , 1 , 'example-website' ) ;
174229 } ) ;
175230
176231 test ( 'Visited TechDoc shows up in top TechDocs' , async ( ) => {
177- const panel = page . locator ( '.v5-MuiPaper-root' , {
178- hasText : 'All TechDocs' ,
179- } ) ;
180- const entries = panel . locator ( 'tbody' ) . locator ( 'tr' ) ;
181- await expect ( entries ) . toHaveCount ( 1 ) ;
232+ const panel = getPanel ( page , translations . techDocs . allTitle ) ;
233+
234+ await verifyPanelContainsTexts ( panel , [
235+ translations . table . headers . name ,
236+ translations . table . headers . entity ,
237+ translations . table . headers . lastUsed ,
238+ translations . table . headers . views ,
239+ ] ) ;
240+
241+ await verifyTableEntries ( panel , 1 , 'docs' ) ;
182242 } ) ;
183243
184244 test ( 'New data shows in searches' , async ( ) => {
185- const panel = page . locator ( '.v5-MuiPaper-root' , { hasText : '1 searches' } ) ;
245+ const panel = getPanel (
246+ page ,
247+ replaceTemplate ( translations . searches . totalCount , { count : 1 } ) ,
248+ ) ;
186249 await panel . scrollIntoViewIfNeeded ( ) ;
187250 await expect ( panel . locator ( '.recharts-surface' ) ) . toBeVisible ( ) ;
188- await expect ( panel ) . toContainText (
189- 'Average search count was 1 per hour for this period.' ,
251+ const averageTextContent = replaceTemplate (
252+ translations . searches . averageText ,
253+ {
254+ count : 1 ,
255+ period : translations . searches . hour ,
256+ } ,
190257 ) ;
258+ const averageText = `${ translations . searches . averagePrefix } ${ averageTextContent } ${ translations . searches . averageSuffix } ` ;
259+ await expect ( panel ) . toContainText ( averageText ) ;
191260 } ) ;
192261
193- test ( 'New data shows in top templates' , async ( ) => {
194- const panel = page . locator ( '.v5-MuiPaper-root' , {
195- hasText : 'All templates' ,
196- } ) ;
262+ test ( 'New data shows in top templates' , async ( {
263+ browser : _browser ,
264+ } , testInfo : TestInfo ) => {
265+ const panel = getPanel ( page , translations . templates . allTitle ) ;
266+ await verifyPanelContainsTexts ( panel , [
267+ translations . table . headers . name ,
268+ translations . table . headers . executions ,
269+ ] ) ;
270+
197271 await panel . scrollIntoViewIfNeeded ( ) ;
198- const entries = panel . locator ( 'tbody' ) . locator ( 'tr ') ;
199- await expect ( entries ) . toHaveCount ( 1 ) ;
200- await expect ( entries ) . toContainText ( 'example-nodejs-template' ) ;
272+ await verifyTableEntries ( panel , 1 , 'example-nodejs-template ') ;
273+
274+ await runAccessibilityTests ( page , testInfo ) ;
201275 } ) ;
202276} ) ;
0 commit comments