Skip to content

Commit 4825ff3

Browse files
fix(6562): update shared explorer to work with iox (#6585)
* chore: move timerage test into a separate file * chore: fix typo in file name for timerange * chore: move saving test into a separate file * chore: add IOx to shared/explorer.test.ts
1 parent 43c27ee commit 4825ff3

File tree

4 files changed

+468
-400
lines changed

4 files changed

+468
-400
lines changed
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
import {Organization} from '../../../src/types'
2+
import {points} from '../../support/commands'
3+
4+
describe('Data Explorer saving', () => {
5+
beforeEach(() => {
6+
cy.flush().then(() =>
7+
cy.signin().then(() =>
8+
cy
9+
.setFeatureFlags({
10+
showOldDataExplorerInNewIOx: true,
11+
showDashboardsInNewIOx: true,
12+
showTasksInNewIOx: true,
13+
showVariablesInNewIOx: true,
14+
})
15+
.then(() => {
16+
cy.get('@org').then(({id}: Organization) => {
17+
cy.createMapVariable(id)
18+
cy.writeData(points(10))
19+
cy.fixture('routes').then(({orgs}) => {
20+
cy.visit(`${orgs}/${id}/data-explorer`)
21+
cy.getByTestID('tree-nav').should('be.visible')
22+
})
23+
})
24+
})
25+
)
26+
)
27+
})
28+
29+
it('can open/close save as dialog and navigate inside', () => {
30+
// open save as
31+
cy.getByTestID('overlay--container').should('not.exist')
32+
cy.getByTestID('save-query-as').click()
33+
cy.getByTestID('overlay--container').should('be.visible')
34+
35+
// test all tabs
36+
cy.get('[id="task"]').click()
37+
cy.getByTestID('task-form-name').should('be.visible')
38+
cy.get('[id="variable"]').click()
39+
cy.getByTestID('flux-editor').should('be.visible')
40+
cy.get('[id="dashboard"]').click()
41+
cy.getByTestID('cell--radio-button').click()
42+
cy.getByTestID('save-as-dashboard-cell--dropdown').should('be.visible')
43+
44+
// close save as
45+
cy.getByTestID('save-as-overlay--header').within(() => {
46+
cy.get('button').click()
47+
})
48+
cy.getByTestID('overlay--container').should('not.exist')
49+
})
50+
51+
describe('as dashboard cell', () => {
52+
const dashboardNames = ['dashboard 1', 'board 2', 'board 3']
53+
const cellName = '📊 graph 1'
54+
const dashboardCreateName = '📋 board'
55+
56+
beforeEach(() => {
57+
cy.get('@org').then(({id: orgID}: Organization) => {
58+
dashboardNames.forEach((d, i) => {
59+
cy.createDashboard(orgID, d).then(({body}) => {
60+
cy.wrap(body.id).as(`dasboard${i}-id`)
61+
})
62+
})
63+
})
64+
65+
// setup query for saving and open dashboard dialog
66+
cy.getByTestID(`selector-list m`).click()
67+
cy.getByTestID(`time-machine-submit-button`).click()
68+
cy.getByTestID('save-query-as').click()
69+
cy.get('[id="dashboard"]').click()
70+
})
71+
72+
it('can save as cell into multiple dashboards', () => {
73+
// input dashboards and cell name
74+
dashboardNames.forEach(name => {
75+
cy.getByTestID('cell--radio-button').click()
76+
cy.getByTestID('save-as-dashboard-cell--dropdown').click()
77+
cy.getByTestID('save-as-dashboard-cell--dropdown-menu').within(() => {
78+
cy.contains(name).click()
79+
})
80+
})
81+
cy.getByTestID('save-as-dashboard-cell--cell-name').type(cellName)
82+
83+
cy.getByTestID('save-as-dashboard-cell--submit').click()
84+
cy.wait(250)
85+
86+
// ensure cell exists at dashboards
87+
cy.get('@org').then(({id: orgID}: Organization) => {
88+
cy.fixture('routes').then(({orgs}) => {
89+
dashboardNames.forEach((_, i) => {
90+
cy.get(`@dasboard${i}-id`).then(id => {
91+
cy.visit(`${orgs}/${orgID}/dashboards/${id}`)
92+
cy.getByTestID('tree-nav')
93+
cy.getByTestID(`cell ${cellName}`).should('exist')
94+
})
95+
})
96+
})
97+
})
98+
})
99+
100+
it('can create new dashboard as saving target', () => {
101+
// select and input new dashboard name and cell name
102+
cy.getByTestID('cell--radio-button').click()
103+
cy.getByTestID('save-as-dashboard-cell--dropdown').click()
104+
cy.getByTestID('save-as-dashboard-cell--dropdown-menu').within(() => {
105+
cy.getByTestID('save-as-dashboard-cell--create-new-dash').click()
106+
})
107+
cy.getByTestID('save-as-dashboard-cell--dashboard-name')
108+
.should('be.visible')
109+
.clear()
110+
.type(dashboardCreateName)
111+
cy.getByTestID('save-as-dashboard-cell--cell-name').type(cellName)
112+
113+
cy.getByTestID('save-as-dashboard-cell--submit').click()
114+
115+
cy.location('pathname').should(
116+
'match',
117+
/^(?=.*dashboards)(?:(?!cell).)+$/
118+
)
119+
120+
cy.getByTestID(`cell--draggable ${cellName}`).should('exist').click()
121+
cy.getByTestID(`cell ${cellName}`).should('exist')
122+
})
123+
})
124+
125+
describe('as a task', () => {
126+
const bucketName = 'bucket 2'
127+
const taskName = '☑ task'
128+
const offset = '30m'
129+
const timeEvery = '50h10m5s'
130+
const timeCron = '0 0 12 * * TUE,FRI,SUN *'
131+
// for strong typings
132+
const cron = 'cron'
133+
const every = 'every'
134+
const both: ('cron' | 'every')[] = [cron, every]
135+
136+
const fillForm = (
137+
type: 'cron' | 'every',
138+
texts: {time?: string; offset?: string; taskName?: string}
139+
) => {
140+
const checkAndType = (target: string, text: string | undefined) => {
141+
cy.getByTestID(target).clear()
142+
if (text) {
143+
cy.getByTestID(target).type(text)
144+
}
145+
}
146+
const {offset, taskName, time} = texts
147+
148+
cy.getByTestID(`task-card-${type}-btn`).click()
149+
checkAndType('task-form-name', taskName)
150+
checkAndType('task-form-schedule-input', time)
151+
checkAndType('task-form-offset-input', offset)
152+
}
153+
154+
const visitTasks = () => {
155+
cy.fixture('routes').then(({orgs}) => {
156+
cy.get('@org').then(({id}: Organization) => {
157+
cy.visit(`${orgs}/${id}/tasks`)
158+
cy.getByTestID('tree-nav')
159+
})
160+
})
161+
}
162+
163+
beforeEach(() => {
164+
cy.get<Organization>('@org').then(({id, name}: Organization) => {
165+
cy.createBucket(id, name, bucketName)
166+
})
167+
cy.get<string>('@defaultBucketListSelector').then(
168+
(defaultBucketListSelector: string) => {
169+
cy.getByTestID(defaultBucketListSelector).click()
170+
cy.getByTestID('nav-item-data-explorer').click({force: true})
171+
cy.getByTestID(`selector-list m`).click()
172+
cy.getByTestID('save-query-as').click({force: true})
173+
cy.get('[id="task"]').click()
174+
}
175+
)
176+
})
177+
178+
// TODO: enable when problem with switching cron/every is fixed
179+
it.skip('should enable/disable submit based on inputs', () => {
180+
both.forEach(type => {
181+
const time = type === 'every' ? timeEvery : timeCron
182+
cy.getByTestID('task-form-save').should('be.disabled')
183+
fillForm(type, {})
184+
cy.getByTestID('task-form-save').should('be.disabled')
185+
fillForm(type, {time, taskName})
186+
cy.getByTestID('task-form-save').should('be.enabled')
187+
fillForm(type, {taskName, offset})
188+
cy.getByTestID('task-form-save').should('be.disabled')
189+
fillForm(type, {time, offset})
190+
cy.getByTestID('task-form-save').should('be.disabled')
191+
})
192+
})
193+
194+
both.forEach(type =>
195+
[true, false].forEach(withOffset => {
196+
it(`can create ${type} task with${
197+
withOffset ? '' : 'out'
198+
} offset`, () => {
199+
const time = type === 'every' ? timeEvery : timeCron
200+
fillForm(type, {time, taskName, ...(withOffset ? {offset} : {})})
201+
cy.getByTestID('task-form-save').click()
202+
203+
visitTasks()
204+
205+
cy.getByTestID('task-card')
206+
.first()
207+
.trigger('mouseover')
208+
.then(() => {
209+
cy.getByTestID('context-menu-task').click()
210+
cy.getByTestID('context-edit-task').click()
211+
})
212+
213+
cy.getByTestID('task-form-schedule-input').should('have.value', time)
214+
cy.getByTestID('task-form-offset-input').should(
215+
'have.value',
216+
withOffset ? offset : ''
217+
)
218+
})
219+
})
220+
)
221+
222+
it('can select buckets', () => {
223+
fillForm('every', {time: timeEvery, taskName})
224+
225+
cy.getByTestID('task-options-bucket-dropdown--button').click()
226+
cy.getByTestID('dropdown-item').contains(bucketName).click()
227+
cy.getByTestID('task-options-bucket-dropdown--button')
228+
.contains(bucketName)
229+
.should('exist')
230+
231+
cy.getByTestID('task-options-bucket-dropdown--button').click()
232+
cy.get<string>('@defaultBucket').then((defaultBucket: string) => {
233+
cy.getByTestID('dropdown-item').contains(defaultBucket).click()
234+
cy.getByTestID('task-options-bucket-dropdown--button')
235+
.contains(defaultBucket)
236+
.should('exist')
237+
238+
cy.getByTestID('task-form-save').click()
239+
})
240+
})
241+
})
242+
243+
describe('as variable', () => {
244+
const variableName = 'var1'
245+
246+
const visitVariables = () => {
247+
cy.fixture('routes').then(({orgs}) => {
248+
cy.get('@org').then(({id}: Organization) => {
249+
cy.visit(`${orgs}/${id}/settings/variables`)
250+
cy.getByTestID('tree-nav')
251+
})
252+
})
253+
}
254+
255+
beforeEach(() => {
256+
cy.getByTestID('nav-item-data-explorer').click({force: true})
257+
cy.getByTestID(`selector-list m`).click()
258+
cy.getByTestID('save-query-as').click({force: true})
259+
cy.get('[id="variable"]').click()
260+
261+
// pre-visit the "Save as variable" tab to prevent race condition
262+
cy.getByTestID('overlay--container').within(() => {
263+
cy.getByTestID('variable-form-save').should('be.disabled')
264+
cy.getByTestID('flux-editor').should('be.visible')
265+
cy.getByTestID('flux-editor').click()
266+
cy.get('.cf-overlay--dismiss').click()
267+
})
268+
})
269+
270+
it('can save and enable/disable submit button', () => {
271+
cy.getByTestID(`selector-list m`).click()
272+
cy.getByTestID('save-query-as').click({force: true})
273+
cy.get('[id="variable"]').click()
274+
275+
cy.getByTestID('overlay--container').within(() => {
276+
cy.getByTestID('variable-form-save').should('be.disabled')
277+
cy.getByTestID('flux-editor').should('be.visible')
278+
cy.getByTestID('variable-name-input').type(variableName)
279+
cy.getByTestID('variable-form-save').should('be.enabled')
280+
cy.getByTestID('variable-name-input').clear()
281+
cy.getByTestID('variable-form-save').should('be.disabled')
282+
cy.getByTestID('flux-editor').should('be.visible')
283+
cy.getByTestID('variable-name-input').type(variableName)
284+
cy.getByTestID('variable-form-save').should('be.enabled')
285+
286+
cy.getByTestID('variable-form-save').click()
287+
})
288+
visitVariables()
289+
cy.getByTestID(`variable-card--name ${variableName}`).should('exist')
290+
})
291+
292+
it('can prevent saving variable names with hyphens or spaces', () => {
293+
cy.getByTestID(`selector-list m`).click()
294+
cy.getByTestID('save-query-as').click({force: true})
295+
cy.get('[id="variable"]').click()
296+
cy.getByTestID('overlay--container').within(() => {
297+
cy.getByTestID('variable-form-save').should('be.disabled')
298+
cy.getByTestID('flux-editor').should('be.visible')
299+
cy.getByTestID('variable-name-input').type('bad name')
300+
cy.getByTestID('variable-form-save').should('be.disabled')
301+
302+
cy.getByTestID('variable-name-input').clear().type('bad-name')
303+
cy.getByTestID('variable-form-save').should('be.disabled')
304+
cy.get('.cf-overlay--dismiss').click()
305+
})
306+
})
307+
})
308+
})

0 commit comments

Comments
 (0)