@nextsparkjs/theme-default 0.1.0-beta.38 → 0.1.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ai-chat/ChatPanel.tsx +1 -1
- package/components/ai-chat/Message.tsx +1 -1
- package/components/ai-chat/MessageInput.tsx +1 -1
- package/components/ai-chat/MessageList.tsx +1 -1
- package/components/ai-chat/TypingIndicator.tsx +1 -1
- package/lib/selectors.ts +2 -3
- package/package.json +3 -2
- package/tests/cypress/e2e/api/_core/billing/BillingAPIController.js +1 -1
- package/tests/cypress/e2e/api/_core/settings/api-keys.crud.cy.ts +1 -1
- package/tests/cypress/e2e/api/_core/users/users-crud.cy.ts +1 -1
- package/tests/cypress/e2e/api/_core/users/users-metas.cy.ts +1 -1
- package/tests/cypress/e2e/api/entities/customers/customers-crud.cy.ts +1 -1
- package/tests/cypress/e2e/api/entities/customers/customers-metas.cy.ts +1 -1
- package/tests/cypress/e2e/api/entities/tasks/tasks-crud.cy.ts +1 -1
- package/tests/cypress/e2e/api/entities/tasks/tasks-metas.cy.ts +1 -1
- package/tests/cypress/e2e/uat/_core/teams/team-switcher.md +2 -2
- package/tests/cypress/src/core/BasePOM.ts +23 -76
- package/tests/cypress/src/core/DashboardEntityPOM.ts +17 -668
- package/tests/cypress/src/entities/TasksPOM.ts +70 -0
- package/tests/cypress/src/helpers/ApiInterceptor.ts +14 -171
- package/tests/cypress.config.ts +12 -17
- package/tests/cypress/e2e/_utils/docs/tutorials/sector7-superadmin-teams.narration.json +0 -155
- package/tests/cypress/e2e/_utils/docs/tutorials/sector7-superadmin.cy.ts +0 -390
- package/tests/cypress/e2e/_utils/docs/tutorials/teams-system.doc.cy.ts +0 -349
- package/tests/cypress/e2e/_utils/docs/tutorials/teams-system.narration.json +0 -165
|
@@ -154,6 +154,42 @@ export class TasksPOM extends DashboardEntityPOM {
|
|
|
154
154
|
return this
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
// ============================================
|
|
158
|
+
// FILTER METHODS
|
|
159
|
+
// ============================================
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Filter tasks by status
|
|
163
|
+
*/
|
|
164
|
+
filterByStatus(status: string) {
|
|
165
|
+
this.selectFilter('status', status)
|
|
166
|
+
return this
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Filter tasks by priority
|
|
171
|
+
*/
|
|
172
|
+
filterByPriority(priority: string) {
|
|
173
|
+
this.selectFilter('priority', priority)
|
|
174
|
+
return this
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Clear status filter
|
|
179
|
+
*/
|
|
180
|
+
clearStatusFilter() {
|
|
181
|
+
this.clearFilter('status')
|
|
182
|
+
return this
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Clear priority filter
|
|
187
|
+
*/
|
|
188
|
+
clearPriorityFilter() {
|
|
189
|
+
this.clearFilter('priority')
|
|
190
|
+
return this
|
|
191
|
+
}
|
|
192
|
+
|
|
157
193
|
// ============================================
|
|
158
194
|
// ENTITY-SPECIFIC ASSERTIONS
|
|
159
195
|
// ============================================
|
|
@@ -171,6 +207,40 @@ export class TasksPOM extends DashboardEntityPOM {
|
|
|
171
207
|
assertTaskNotInList(title: string) {
|
|
172
208
|
return this.assertNotInList(title)
|
|
173
209
|
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Assert task has specific status in list
|
|
213
|
+
*/
|
|
214
|
+
assertTaskStatus(title: string, status: string) {
|
|
215
|
+
cy.contains(this.selectors.rowGeneric, title)
|
|
216
|
+
.should('contain.text', status)
|
|
217
|
+
return this
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Assert task has specific priority in list
|
|
222
|
+
*/
|
|
223
|
+
assertTaskPriority(title: string, priority: string) {
|
|
224
|
+
cy.contains(this.selectors.rowGeneric, title)
|
|
225
|
+
.should('contain.text', priority)
|
|
226
|
+
return this
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Assert task count in list
|
|
231
|
+
*/
|
|
232
|
+
assertTaskCount(count: number) {
|
|
233
|
+
cy.get(this.selectors.rowGeneric).should('have.length', count)
|
|
234
|
+
return this
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Assert no tasks in list
|
|
239
|
+
*/
|
|
240
|
+
assertNoTasks() {
|
|
241
|
+
cy.get(this.selectors.rowGeneric).should('not.exist')
|
|
242
|
+
return this
|
|
243
|
+
}
|
|
174
244
|
}
|
|
175
245
|
|
|
176
246
|
export default TasksPOM
|
|
@@ -1,177 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ApiInterceptor -
|
|
2
|
+
* ApiInterceptor - Re-export from @nextsparkjs/testing
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The ApiInterceptor class is provided by @nextsparkjs/testing.
|
|
5
|
+
* This file exists for backward compatibility and to allow
|
|
6
|
+
* theme-specific extensions if needed.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* cy.visit('/dashboard/customers')
|
|
11
|
-
* api.waitForList()
|
|
8
|
+
* @example Basic usage:
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { ApiInterceptor } from '../helpers/ApiInterceptor'
|
|
12
11
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
12
|
+
* const api = new ApiInterceptor('tasks')
|
|
13
|
+
* api.setupCrudIntercepts()
|
|
14
|
+
* cy.visit('/dashboard/tasks')
|
|
15
|
+
* api.waitForList()
|
|
16
|
+
* ```
|
|
18
17
|
*/
|
|
19
18
|
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
slug: string
|
|
23
|
-
/** Ruta API custom (ej: '/api/v1/post-categories') */
|
|
24
|
-
customPath?: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class ApiInterceptor {
|
|
28
|
-
private slug: string
|
|
29
|
-
private endpoint: string
|
|
30
|
-
|
|
31
|
-
constructor(slugOrConfig: string | ApiInterceptorConfig) {
|
|
32
|
-
if (typeof slugOrConfig === 'string') {
|
|
33
|
-
this.slug = slugOrConfig
|
|
34
|
-
this.endpoint = `/api/v1/${slugOrConfig}`
|
|
35
|
-
} else {
|
|
36
|
-
this.slug = slugOrConfig.slug
|
|
37
|
-
this.endpoint = slugOrConfig.customPath || `/api/v1/${slugOrConfig.slug}`
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ============================================
|
|
42
|
-
// ACCESSORS
|
|
43
|
-
// ============================================
|
|
44
|
-
|
|
45
|
-
/** Get the API endpoint path */
|
|
46
|
-
get path(): string {
|
|
47
|
-
return this.endpoint
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** Get the entity slug */
|
|
51
|
-
get entitySlug(): string {
|
|
52
|
-
return this.slug
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** Get alias names for all operations */
|
|
56
|
-
get aliases() {
|
|
57
|
-
return {
|
|
58
|
-
list: `${this.slug}List`,
|
|
59
|
-
create: `${this.slug}Create`,
|
|
60
|
-
update: `${this.slug}Update`,
|
|
61
|
-
delete: `${this.slug}Delete`
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ============================================
|
|
66
|
-
// INTERCEPT SETUP
|
|
67
|
-
// ============================================
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Setup intercepts for all CRUD operations
|
|
71
|
-
* Call this BEFORE navigation in beforeEach or at test start
|
|
72
|
-
*
|
|
73
|
-
* Note: We intercept both PUT and PATCH for updates since different
|
|
74
|
-
* APIs may use different HTTP methods for updates.
|
|
75
|
-
*/
|
|
76
|
-
setupCrudIntercepts(): this {
|
|
77
|
-
cy.intercept('GET', `${this.endpoint}*`).as(this.aliases.list)
|
|
78
|
-
cy.intercept('POST', this.endpoint).as(this.aliases.create)
|
|
79
|
-
// Intercept both PUT and PATCH for updates (APIs may use either)
|
|
80
|
-
cy.intercept('PUT', `${this.endpoint}/*`).as(this.aliases.update)
|
|
81
|
-
cy.intercept('PATCH', `${this.endpoint}/*`).as(`${this.aliases.update}Patch`)
|
|
82
|
-
cy.intercept('DELETE', `${this.endpoint}/*`).as(this.aliases.delete)
|
|
83
|
-
return this
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Setup only list + create intercepts
|
|
88
|
-
* Useful for list pages with inline create
|
|
89
|
-
*/
|
|
90
|
-
setupListIntercepts(): this {
|
|
91
|
-
cy.intercept('GET', `${this.endpoint}*`).as(this.aliases.list)
|
|
92
|
-
cy.intercept('POST', this.endpoint).as(this.aliases.create)
|
|
93
|
-
return this
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// ============================================
|
|
97
|
-
// WAIT METHODS
|
|
98
|
-
// ============================================
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Wait for list response (GET)
|
|
102
|
-
* Use after navigation or after mutations to wait for refresh
|
|
103
|
-
*/
|
|
104
|
-
waitForList(timeout = 10000): Cypress.Chainable {
|
|
105
|
-
return cy.wait(`@${this.aliases.list}`, { timeout })
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Wait for create response (POST) and validate success status
|
|
110
|
-
*/
|
|
111
|
-
waitForCreate(timeout = 10000): Cypress.Chainable {
|
|
112
|
-
return cy.wait(`@${this.aliases.create}`, { timeout })
|
|
113
|
-
.its('response.statusCode')
|
|
114
|
-
.should('be.oneOf', [200, 201])
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Wait for update response (PATCH or PUT) and validate success status
|
|
119
|
-
* Waits for PATCH first (more common), falls back to PUT
|
|
120
|
-
*/
|
|
121
|
-
waitForUpdate(timeout = 10000): Cypress.Chainable {
|
|
122
|
-
// Try PATCH first (more common in modern APIs), fall back to PUT
|
|
123
|
-
return cy.wait(`@${this.aliases.update}Patch`, { timeout })
|
|
124
|
-
.its('response.statusCode')
|
|
125
|
-
.should('be.oneOf', [200, 201])
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Wait for delete response (DELETE) and validate success status
|
|
130
|
-
*/
|
|
131
|
-
waitForDelete(timeout = 10000): Cypress.Chainable {
|
|
132
|
-
return cy.wait(`@${this.aliases.delete}`, { timeout })
|
|
133
|
-
.its('response.statusCode')
|
|
134
|
-
.should('be.oneOf', [200, 204])
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// ============================================
|
|
138
|
-
// CONVENIENCE METHODS
|
|
139
|
-
// ============================================
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Wait for list refresh (alias for waitForList)
|
|
143
|
-
* Semantic name for use after create/update/delete
|
|
144
|
-
*/
|
|
145
|
-
waitForRefresh(timeout = 10000): Cypress.Chainable {
|
|
146
|
-
return this.waitForList(timeout)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Wait for create + list refresh
|
|
151
|
-
* Common pattern: create entity, wait for success, wait for list to refresh
|
|
152
|
-
*/
|
|
153
|
-
waitForCreateAndRefresh(timeout = 10000): Cypress.Chainable {
|
|
154
|
-
this.waitForCreate(timeout)
|
|
155
|
-
return this.waitForList(timeout)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Wait for update + list refresh
|
|
160
|
-
* Common pattern: update entity, wait for success, wait for list to refresh
|
|
161
|
-
*/
|
|
162
|
-
waitForUpdateAndRefresh(timeout = 10000): Cypress.Chainable {
|
|
163
|
-
this.waitForUpdate(timeout)
|
|
164
|
-
return this.waitForList(timeout)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Wait for delete + list refresh
|
|
169
|
-
* Common pattern: delete entity, wait for success, wait for list to refresh
|
|
170
|
-
*/
|
|
171
|
-
waitForDeleteAndRefresh(timeout = 10000): Cypress.Chainable {
|
|
172
|
-
this.waitForDelete(timeout)
|
|
173
|
-
return this.waitForList(timeout)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export default ApiInterceptor
|
|
19
|
+
// Re-export from testing package
|
|
20
|
+
export { ApiInterceptor, type ApiInterceptorConfig } from '@nextsparkjs/testing/helpers'
|
package/tests/cypress.config.ts
CHANGED
|
@@ -10,8 +10,11 @@
|
|
|
10
10
|
import { defineConfig } from 'cypress'
|
|
11
11
|
import path from 'path'
|
|
12
12
|
import fs from 'fs'
|
|
13
|
+
import { fileURLToPath } from 'url'
|
|
13
14
|
|
|
14
|
-
// __dirname
|
|
15
|
+
// ESM-compatible __dirname
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
17
|
+
const __dirname = path.dirname(__filename)
|
|
15
18
|
|
|
16
19
|
// Paths relative to this config file
|
|
17
20
|
const themeRoot = path.resolve(__dirname, '..')
|
|
@@ -52,22 +55,14 @@ export default defineConfig({
|
|
|
52
55
|
// Base URL for the application
|
|
53
56
|
baseUrl: `http://localhost:${port}`,
|
|
54
57
|
|
|
55
|
-
// Spec patterns: theme tests
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
path.join(projectRoot, 'packages/core/tests/cypress/e2e/core/**/*.cy.{js,ts}'),
|
|
64
|
-
path.join(__dirname, 'cypress/e2e/**/*.cy.{js,ts}'),
|
|
65
|
-
],
|
|
66
|
-
|
|
67
|
-
// Support file (theme-local in npm mode, core in monorepo)
|
|
68
|
-
supportFile: isNpmMode
|
|
69
|
-
? path.join(__dirname, 'cypress/support/e2e.ts')
|
|
70
|
-
: path.join(projectRoot, 'packages/core/tests/cypress/support/e2e.ts'),
|
|
58
|
+
// Spec patterns: theme tests only
|
|
59
|
+
// Note: core e2e tests were removed as they were empty
|
|
60
|
+
specPattern: [
|
|
61
|
+
path.join(__dirname, 'cypress/e2e/**/*.cy.{js,ts}'),
|
|
62
|
+
],
|
|
63
|
+
|
|
64
|
+
// Support file (always theme-local)
|
|
65
|
+
supportFile: path.join(__dirname, 'cypress/support/e2e.ts'),
|
|
71
66
|
|
|
72
67
|
// Fixtures folder (theme-specific)
|
|
73
68
|
fixturesFolder: path.join(__dirname, 'cypress/fixtures'),
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"title": "Sector 7 - SuperAdmin Teams View",
|
|
3
|
-
"description": "Tutorial que muestra cómo un super administrador puede acceder a Sector 7 y visualizar todos los equipos del sistema.",
|
|
4
|
-
"language": "es",
|
|
5
|
-
"estimatedDuration": "1-1:30 minutos",
|
|
6
|
-
"targetAudience": "Usuarios finales con rol superadmin",
|
|
7
|
-
"chapters": [
|
|
8
|
-
{
|
|
9
|
-
"id": "intro",
|
|
10
|
-
"title": "Introducción",
|
|
11
|
-
"narrations": [
|
|
12
|
-
{
|
|
13
|
-
"step": 1,
|
|
14
|
-
"text": "Bienvenido a Sector 7, el área exclusiva para super administradores.",
|
|
15
|
-
"action": "none",
|
|
16
|
-
"estimatedSeconds": 4
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"step": 2,
|
|
20
|
-
"text": "Hoy veremos cómo acceder y visualizar todos los equipos del sistema.",
|
|
21
|
-
"action": "none",
|
|
22
|
-
"estimatedSeconds": 4
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "login",
|
|
28
|
-
"title": "Login como SuperAdmin",
|
|
29
|
-
"narrations": [
|
|
30
|
-
{
|
|
31
|
-
"step": 3,
|
|
32
|
-
"text": "Iniciamos sesión con las credenciales de superadmin.",
|
|
33
|
-
"action": "visit-login",
|
|
34
|
-
"estimatedSeconds": 3
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"step": 4,
|
|
38
|
-
"text": "Usamos el email del superadmin de prueba.",
|
|
39
|
-
"action": "fill-email",
|
|
40
|
-
"estimatedSeconds": 4
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"step": 5,
|
|
44
|
-
"text": "Ingresamos la contraseña y enviamos.",
|
|
45
|
-
"action": "fill-password-submit",
|
|
46
|
-
"estimatedSeconds": 5
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"step": 6,
|
|
50
|
-
"text": "Acceso concedido. Observa el icono de Sector 7 en la barra superior.",
|
|
51
|
-
"action": "highlight-sector7-icon",
|
|
52
|
-
"estimatedSeconds": 5
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"id": "navigation",
|
|
58
|
-
"title": "Navegación a Sector 7",
|
|
59
|
-
"narrations": [
|
|
60
|
-
{
|
|
61
|
-
"step": 7,
|
|
62
|
-
"text": "Hacemos clic para ingresar al área restringida.",
|
|
63
|
-
"action": "click-sector7",
|
|
64
|
-
"estimatedSeconds": 3
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"step": 8,
|
|
68
|
-
"text": "Este es el panel de control del super administrador.",
|
|
69
|
-
"action": "show-dashboard",
|
|
70
|
-
"estimatedSeconds": 5
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"step": 9,
|
|
74
|
-
"text": "En el menú lateral vemos las opciones disponibles.",
|
|
75
|
-
"action": "highlight-teams-nav",
|
|
76
|
-
"estimatedSeconds": 4
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"id": "teams-view",
|
|
82
|
-
"title": "Visualización de Teams",
|
|
83
|
-
"narrations": [
|
|
84
|
-
{
|
|
85
|
-
"step": 10,
|
|
86
|
-
"text": "Navegamos a la sección de Equipos.",
|
|
87
|
-
"action": "click-teams-nav",
|
|
88
|
-
"estimatedSeconds": 3
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"step": 11,
|
|
92
|
-
"text": "Aquí vemos todos los equipos del sistema con estadísticas.",
|
|
93
|
-
"action": "show-stats",
|
|
94
|
-
"estimatedSeconds": 5
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
"step": 12,
|
|
98
|
-
"text": "La pestaña Work Teams muestra equipos colaborativos.",
|
|
99
|
-
"action": "highlight-work-tab",
|
|
100
|
-
"estimatedSeconds": 4
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"step": 13,
|
|
104
|
-
"text": "También podemos ver los equipos personales de cada usuario.",
|
|
105
|
-
"action": "click-personal-tab",
|
|
106
|
-
"estimatedSeconds": 5
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
"step": 14,
|
|
110
|
-
"text": "El buscador permite filtrar equipos por nombre o email del propietario.",
|
|
111
|
-
"action": "highlight-search",
|
|
112
|
-
"estimatedSeconds": 4
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"id": "conclusion",
|
|
118
|
-
"title": "Conclusión",
|
|
119
|
-
"narrations": [
|
|
120
|
-
{
|
|
121
|
-
"step": 15,
|
|
122
|
-
"text": "Así funciona Sector 7: acceso exclusivo a la gestión global del sistema.",
|
|
123
|
-
"action": "none",
|
|
124
|
-
"estimatedSeconds": 5
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
"step": 16,
|
|
128
|
-
"text": "Gracias por ver este tutorial.",
|
|
129
|
-
"action": "none",
|
|
130
|
-
"estimatedSeconds": 3
|
|
131
|
-
}
|
|
132
|
-
]
|
|
133
|
-
}
|
|
134
|
-
],
|
|
135
|
-
"totalSteps": 16,
|
|
136
|
-
"technicalNotes": {
|
|
137
|
-
"users": {
|
|
138
|
-
"superadmin": "superadmin@cypress.com",
|
|
139
|
-
"password": "Pandora1234"
|
|
140
|
-
},
|
|
141
|
-
"routes": [
|
|
142
|
-
"/login",
|
|
143
|
-
"/dashboard",
|
|
144
|
-
"/sector7",
|
|
145
|
-
"/sector7/teams"
|
|
146
|
-
],
|
|
147
|
-
"selectors": {
|
|
148
|
-
"topnavSector7": "[data-cy='topnav-sector7']",
|
|
149
|
-
"sector7NavTeams": "[data-cy='sector7-nav-teams']",
|
|
150
|
-
"teamsSearchInput": "[data-cy='teams-search-input']",
|
|
151
|
-
"workTeamsTab": "[value='work']",
|
|
152
|
-
"personalTeamsTab": "[value='personal']"
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|