|
| 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