chore: Add Cypress tests for drill by (#23849)
This commit is contained in:
parent
31d33592ef
commit
60046ca1cc
|
|
@ -0,0 +1,705 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { Interception } from 'cypress/types/net-stubbing';
|
||||
import { waitForChartLoad } from 'cypress/utils';
|
||||
import { SUPPORTED_CHARTS_DASHBOARD } from 'cypress/utils/urls';
|
||||
import {
|
||||
openTopLevelTab,
|
||||
SUPPORTED_TIER1_CHARTS,
|
||||
SUPPORTED_TIER2_CHARTS,
|
||||
} from './utils';
|
||||
import {
|
||||
interceptExploreJson,
|
||||
interceptV1ChartData,
|
||||
interceptFormDataKey,
|
||||
} from '../explore/utils';
|
||||
|
||||
const closeModal = () => {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find('[data-test="close-drill-by-modal"]').length) {
|
||||
cy.getBySel('close-drill-by-modal').click({ force: true });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const openTableContextMenu = (
|
||||
cellContent: string,
|
||||
tableSelector = "[data-test-viz-type='table']",
|
||||
) => {
|
||||
cy.get(tableSelector)
|
||||
.scrollIntoView()
|
||||
.contains(cellContent)
|
||||
.first()
|
||||
.rightclick();
|
||||
};
|
||||
|
||||
const drillBy = (targetDrillByColumn: string, isLegacy = false) => {
|
||||
if (isLegacy) {
|
||||
interceptExploreJson('legacyData');
|
||||
} else {
|
||||
interceptV1ChartData();
|
||||
}
|
||||
|
||||
cy.get('.ant-dropdown:not(.ant-dropdown-hidden)')
|
||||
.first()
|
||||
.find("[role='menu'] [role='menuitem'] [title='Drill by']")
|
||||
.trigger('mouseover');
|
||||
cy.get(
|
||||
'.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-hidden) [data-test="drill-by-submenu"]',
|
||||
)
|
||||
.find('[role="menuitem"]')
|
||||
.contains(new RegExp(`^${targetDrillByColumn}$`))
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
if (isLegacy) {
|
||||
return cy.wait('@legacyData');
|
||||
}
|
||||
return cy.wait('@v1Data');
|
||||
};
|
||||
|
||||
const verifyExpectedFormData = (
|
||||
interceptedRequest: Interception,
|
||||
expectedFormData: Record<string, any>,
|
||||
) => {
|
||||
const actualFormData = interceptedRequest.request.body?.form_data;
|
||||
Object.entries(expectedFormData).forEach(([key, val]) => {
|
||||
expect(actualFormData?.[key]).to.eql(val);
|
||||
});
|
||||
};
|
||||
|
||||
const testEchart = (
|
||||
vizType: string,
|
||||
chartName: string,
|
||||
drillClickCoordinates: [[number, number], [number, number]],
|
||||
furtherDrillDimension = 'name',
|
||||
) => {
|
||||
cy.get(`[data-test-viz-type='${vizType}'] canvas`).then($canvas => {
|
||||
// click 'boy'
|
||||
cy.wrap($canvas)
|
||||
.scrollIntoView()
|
||||
.trigger(
|
||||
'mouseover',
|
||||
drillClickCoordinates[0][0],
|
||||
drillClickCoordinates[0][1],
|
||||
)
|
||||
.rightclick(drillClickCoordinates[0][0], drillClickCoordinates[0][1]);
|
||||
|
||||
drillBy('state').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: ['state'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.getBySel(`"Drill by: ${chartName}-modal"`).as('drillByModal');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.draggable-trigger')
|
||||
.should('contain', chartName);
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'state');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
|
||||
// further drill
|
||||
cy.get(`[data-test="drill-by-chart"] canvas`).then($canvas => {
|
||||
// click 'other'
|
||||
cy.wrap($canvas)
|
||||
.scrollIntoView()
|
||||
.trigger(
|
||||
'mouseover',
|
||||
drillClickCoordinates[1][0],
|
||||
drillClickCoordinates[1][1],
|
||||
)
|
||||
.rightclick(drillClickCoordinates[1][0], drillClickCoordinates[1][1]);
|
||||
|
||||
drillBy(furtherDrillDimension).then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: [furtherDrillDimension],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'other',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'state',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
|
||||
// undo - back to drill by state
|
||||
interceptV1ChartData('drillByUndo');
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'state (other)')
|
||||
.and('contain', furtherDrillDimension)
|
||||
.contains('state (other)')
|
||||
.click();
|
||||
cy.wait('@drillByUndo').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: ['state'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('not.contain', 'state (other)')
|
||||
.and('not.contain', furtherDrillDimension)
|
||||
.and('contain', 'state');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
describe('Drill by modal', () => {
|
||||
beforeEach(() => {
|
||||
closeModal();
|
||||
});
|
||||
before(() => {
|
||||
cy.visit(SUPPORTED_CHARTS_DASHBOARD);
|
||||
});
|
||||
|
||||
describe('Modal actions + Table', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
openTopLevelTab('Tier 1');
|
||||
SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
it('opens the modal from the context menu', () => {
|
||||
openTableContextMenu('boy');
|
||||
drillBy('state').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: ['state'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.getBySel('"Drill by: Table-modal"').as('drillByModal');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.draggable-trigger')
|
||||
.should('contain', 'Drill by: Table');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="metadata-bar"]')
|
||||
.should('be.visible');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'state');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('contain', 'state')
|
||||
.and('contain', 'sum__num');
|
||||
|
||||
// further drilling
|
||||
openTableContextMenu('CA', '[data-test="drill-by-chart"]');
|
||||
drillBy('name').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: ['name'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'CA',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'state',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('not.contain', 'state')
|
||||
.and('contain', 'name')
|
||||
.and('contain', 'sum__num');
|
||||
|
||||
// undo - back to drill by state
|
||||
interceptV1ChartData('drillByUndo');
|
||||
interceptFormDataKey();
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'state (CA)')
|
||||
.and('contain', 'name')
|
||||
.contains('state (CA)')
|
||||
.click();
|
||||
cy.wait('@drillByUndo').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupby: ['state'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('not.contain', 'name')
|
||||
.and('contain', 'state')
|
||||
.and('contain', 'sum__num');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('not.contain', 'state (CA)')
|
||||
.and('not.contain', 'name')
|
||||
.and('contain', 'state');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-display-toggle"]')
|
||||
.contains('Table')
|
||||
.click();
|
||||
|
||||
cy.getBySel('drill-by-chart').should('not.exist');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-results-table"]')
|
||||
.should('be.visible');
|
||||
|
||||
cy.wait('@formDataKey').then(intercept => {
|
||||
cy.get('@drillByModal')
|
||||
.contains('Edit chart')
|
||||
.should('have.attr', 'href')
|
||||
.and(
|
||||
'contain',
|
||||
`/explore/?form_data_key=${intercept.response?.body?.key}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tier 1 charts', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
openTopLevelTab('Tier 1');
|
||||
SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
it('Pivot Table', () => {
|
||||
openTableContextMenu('boy', "[data-test-viz-type='pivot_table_v2']");
|
||||
drillBy('name').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupbyRows: ['state'],
|
||||
groupbyColumns: ['name'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.getBySel('"Drill by: Pivot Table-modal"').as('drillByModal');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.draggable-trigger')
|
||||
.should('contain', 'Drill by: Pivot Table');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'name');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('contain', 'state')
|
||||
.and('contain', 'name')
|
||||
.and('contain', 'sum__num')
|
||||
.and('not.contain', 'Gender');
|
||||
|
||||
openTableContextMenu('CA', '[data-test="drill-by-chart"]');
|
||||
drillBy('ds').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupbyColumns: ['name'],
|
||||
groupbyRows: ['ds'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'CA',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'state',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('contain', 'name')
|
||||
.and('contain', 'ds')
|
||||
.and('contain', 'sum__num')
|
||||
.and('not.contain', 'state');
|
||||
|
||||
interceptV1ChartData('drillByUndo');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'name (CA)')
|
||||
.and('contain', 'ds')
|
||||
.contains('name (CA)')
|
||||
.click();
|
||||
cy.wait('@drillByUndo').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
groupbyRows: ['state'],
|
||||
groupbyColumns: ['name'],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'boy',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
operatorId: 'EQUALS',
|
||||
subject: 'gender',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible')
|
||||
.and('not.contain', 'ds')
|
||||
.and('contain', 'state')
|
||||
.and('contain', 'name')
|
||||
.and('contain', 'sum__num');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('not.contain', 'name (CA)')
|
||||
.and('not.contain', 'ds')
|
||||
.and('contain', 'name');
|
||||
});
|
||||
|
||||
it('Line chart', () => {
|
||||
testEchart('echarts_timeseries_line', 'Time-Series Line Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Area Chart', () => {
|
||||
testEchart('echarts_area', 'Time-Series Area Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Time-Series Scatter Chart', () => {
|
||||
testEchart('echarts_timeseries_scatter', 'Time-Series Scatter Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Time-Series Bar Chart V2', () => {
|
||||
testEchart('echarts_timeseries_bar', 'Time-Series Bar Chart V2', [
|
||||
[70, 94],
|
||||
[362, 68],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Pie Chart', () => {
|
||||
testEchart('pie', 'Pie Chart', [
|
||||
[243, 167],
|
||||
[534, 248],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tier 2 charts', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
openTopLevelTab('Tier 2');
|
||||
SUPPORTED_TIER2_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
it('Box Plot Chart', () => {
|
||||
testEchart(
|
||||
'box_plot',
|
||||
'Box Plot Chart',
|
||||
[
|
||||
[139, 277],
|
||||
[787, 441],
|
||||
],
|
||||
'ds',
|
||||
);
|
||||
});
|
||||
|
||||
it('Time-Series Generic Chart', () => {
|
||||
testEchart('echarts_timeseries', 'Time-Series Generic Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Time-Series Smooth Line Chart', () => {
|
||||
testEchart('echarts_timeseries_smooth', 'Time-Series Smooth Line Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Time-Series Step Line Chart', () => {
|
||||
testEchart('echarts_timeseries_step', 'Time-Series Step Line Chart', [
|
||||
[70, 93],
|
||||
[70, 93],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Funnel Chart', () => {
|
||||
testEchart('funnel', 'Funnel Chart', [
|
||||
[154, 80],
|
||||
[421, 39],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Gauge Chart', () => {
|
||||
testEchart('gauge_chart', 'Gauge Chart', [
|
||||
[151, 95],
|
||||
[300, 143],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Radar Chart', () => {
|
||||
testEchart('radar', 'Radar Chart', [
|
||||
[182, 49],
|
||||
[423, 91],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Treemap V2 Chart', () => {
|
||||
testEchart('treemap_v2', 'Treemap V2 Chart', [
|
||||
[145, 84],
|
||||
[220, 105],
|
||||
]);
|
||||
});
|
||||
|
||||
it('Mixed Chart', () => {
|
||||
cy.get('[data-test-viz-type="mixed_timeseries"] canvas').then($canvas => {
|
||||
// click 'boy'
|
||||
cy.wrap($canvas)
|
||||
.scrollIntoView()
|
||||
.trigger('mouseover', 70, 93)
|
||||
.rightclick(70, 93);
|
||||
|
||||
drillBy('name').then(intercepted => {
|
||||
const { queries } = intercepted.request.body;
|
||||
expect(queries[0].columns).to.eql(['name']);
|
||||
expect(queries[0].filters).to.eql([
|
||||
{ col: 'gender', op: '==', val: 'boy' },
|
||||
]);
|
||||
expect(queries[1].columns).to.eql(['state']);
|
||||
expect(queries[1].filters).to.eql([]);
|
||||
});
|
||||
|
||||
cy.getBySel('"Drill by: Mixed Chart-modal"').as('drillByModal');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.draggable-trigger')
|
||||
.should('contain', 'Mixed Chart');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'name');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
|
||||
// further drill
|
||||
cy.get(`[data-test="drill-by-chart"] canvas`).then($canvas => {
|
||||
// click second query
|
||||
cy.wrap($canvas)
|
||||
.scrollIntoView()
|
||||
.trigger('mouseover', 246, 114)
|
||||
.rightclick(246, 114);
|
||||
|
||||
drillBy('ds').then(intercepted => {
|
||||
const { queries } = intercepted.request.body;
|
||||
expect(queries[0].columns).to.eql(['name']);
|
||||
expect(queries[0].filters).to.eql([
|
||||
{ col: 'gender', op: '==', val: 'boy' },
|
||||
]);
|
||||
expect(queries[1].columns).to.eql(['ds']);
|
||||
expect(queries[1].filters).to.eql([
|
||||
{ col: 'state', op: '==', val: 'other' },
|
||||
]);
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
|
||||
// undo - back to drill by state
|
||||
interceptV1ChartData('drillByUndo');
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('contain', 'name (other)')
|
||||
.and('contain', 'ds')
|
||||
.contains('name (other)')
|
||||
.click();
|
||||
|
||||
cy.wait('@drillByUndo').then(intercepted => {
|
||||
const { queries } = intercepted.request.body;
|
||||
expect(queries[0].columns).to.eql(['name']);
|
||||
expect(queries[0].filters).to.eql([
|
||||
{ col: 'gender', op: '==', val: 'boy' },
|
||||
]);
|
||||
expect(queries[1].columns).to.eql(['state']);
|
||||
expect(queries[1].filters).to.eql([]);
|
||||
});
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('.ant-breadcrumb')
|
||||
.should('be.visible')
|
||||
.and('contain', 'gender (boy)')
|
||||
.and('contain', '/')
|
||||
.and('not.contain', 'name (other)')
|
||||
.and('not.contain', 'ds')
|
||||
.and('contain', 'name');
|
||||
|
||||
cy.get('@drillByModal')
|
||||
.find('[data-test="drill-by-chart"]')
|
||||
.should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -18,7 +18,11 @@
|
|||
*/
|
||||
import { waitForChartLoad } from 'cypress/utils';
|
||||
import { SUPPORTED_CHARTS_DASHBOARD } from 'cypress/utils/urls';
|
||||
import { SUPPORTED_TIER1_CHARTS, SUPPORTED_TIER2_CHARTS } from './utils';
|
||||
import {
|
||||
openTopLevelTab,
|
||||
SUPPORTED_TIER1_CHARTS,
|
||||
SUPPORTED_TIER2_CHARTS,
|
||||
} from './utils';
|
||||
|
||||
function interceptSamples() {
|
||||
cy.intercept(`/datasource/samples*`).as('samples');
|
||||
|
|
@ -77,10 +81,6 @@ function closeModal() {
|
|||
});
|
||||
}
|
||||
|
||||
function setTopLevelTab(tabName: string) {
|
||||
cy.get("div#TABS-TOP div[role='tab']").contains(tabName).click();
|
||||
}
|
||||
|
||||
function testTimeChart(vizType: string) {
|
||||
interceptSamples();
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ describe('Drill to detail modal', () => {
|
|||
describe('Tier 1 charts', () => {
|
||||
before(() => {
|
||||
cy.visit(SUPPORTED_CHARTS_DASHBOARD);
|
||||
setTopLevelTab('Tier 1');
|
||||
openTopLevelTab('Tier 1');
|
||||
SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
|
|
@ -438,7 +438,7 @@ describe('Drill to detail modal', () => {
|
|||
describe('Tier 2 charts', () => {
|
||||
before(() => {
|
||||
cy.visit(SUPPORTED_CHARTS_DASHBOARD);
|
||||
setTopLevelTab('Tier 2');
|
||||
openTopLevelTab('Tier 2');
|
||||
SUPPORTED_TIER2_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,24 @@ export const SUPPORTED_TIER1_CHARTS = [
|
|||
{ name: 'Big Number', viz: 'big_number_total' },
|
||||
{ name: 'Big Number with Trendline', viz: 'big_number' },
|
||||
{ name: 'Pie Chart', viz: 'pie' },
|
||||
{ name: 'Table', viz: 'table' },
|
||||
{ name: 'Pivot Table', viz: 'pivot_table_v2' },
|
||||
{ name: 'Time-Series Line Chart', viz: 'echarts_timeseries_line' },
|
||||
{ name: 'Time-Series Area Chart', viz: 'echarts_area' },
|
||||
{ name: 'Time-Series Scatter Chart', viz: 'echarts_timeseries_scatter' },
|
||||
{ name: 'Time-Series Bar Chart V2', viz: 'echarts_timeseries_bar' },
|
||||
] as ChartSpec[];
|
||||
|
||||
export const SUPPORTED_TIER2_CHARTS = [
|
||||
{ name: 'Box Plot Chart', viz: 'box_plot' },
|
||||
{ name: 'Time-Series Generic Chart', viz: 'echarts_timeseries' },
|
||||
{ name: 'Time-Series Smooth Line Chart', viz: 'echarts_timeseries_smooth' },
|
||||
{ name: 'Time-Series Step Line Chart', viz: 'echarts_timeseries_step' },
|
||||
{ name: 'Funnel Chart', viz: 'funnel' },
|
||||
{ name: 'Gauge Chart', viz: 'gauge_chart' },
|
||||
{ name: 'Radar Chart', viz: 'radar' },
|
||||
{ name: 'Treemap V2 Chart', viz: 'treemap_v2' },
|
||||
{ name: 'Mixed Chart', viz: 'mixed_timeseries' },
|
||||
] as ChartSpec[];
|
||||
|
||||
export const testItems = {
|
||||
|
|
@ -515,3 +529,7 @@ export function openTab(tabComponentIndex: number, tabIndex: number) {
|
|||
.eq(tabIndex)
|
||||
.click();
|
||||
}
|
||||
|
||||
export const openTopLevelTab = (tabName: string) => {
|
||||
cy.get("div#TABS-TOP div[role='tab']").contains(tabName).click();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,13 +35,17 @@ export function interceptUpdate() {
|
|||
cy.intercept('PUT', `/api/v1/chart/*`).as('update');
|
||||
}
|
||||
|
||||
export function interceptPost() {
|
||||
cy.intercept('POST', `/api/v1/chart/`).as('post');
|
||||
export const interceptV1ChartData = (alias = 'v1Data') => {
|
||||
cy.intercept('/api/v1/chart/data*').as(alias);
|
||||
};
|
||||
|
||||
export function interceptExploreJson(alias = 'getJson') {
|
||||
cy.intercept('POST', `/superset/explore_json/**`).as(alias);
|
||||
}
|
||||
|
||||
export function interceptExploreJson() {
|
||||
cy.intercept('POST', `/superset/explore_json/**`).as('getJson');
|
||||
}
|
||||
export const interceptFormDataKey = () => {
|
||||
cy.intercept('POST', '/api/v1/explore/form_data').as('formDataKey');
|
||||
};
|
||||
|
||||
export function interceptExploreGet() {
|
||||
cy.intercept({
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ export default function DrillByChart({
|
|||
height: 100%;
|
||||
min-height: 0;
|
||||
`}
|
||||
data-test="drill-by-chart"
|
||||
>
|
||||
<SuperChart
|
||||
disableErrorBoundary
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export const useDisplayModeToggle = () => {
|
|||
box-shadow: none;
|
||||
}
|
||||
`}
|
||||
data-test="drill-by-display-toggle"
|
||||
>
|
||||
<Radio.Group
|
||||
onChange={({ target: { value } }) => {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export const useResultsTableView = (
|
|||
}
|
||||
if (chartDataResult.length === 1) {
|
||||
return (
|
||||
<PaginationContainer>
|
||||
<PaginationContainer data-test="drill-by-results-table">
|
||||
<SingleQueryResultPane
|
||||
colnames={chartDataResult[0].colnames}
|
||||
coltypes={chartDataResult[0].coltypes}
|
||||
|
|
@ -53,7 +53,7 @@ export const useResultsTableView = (
|
|||
);
|
||||
}
|
||||
return (
|
||||
<Tabs fullWidth={false}>
|
||||
<Tabs fullWidth={false} data-test="drill-by-results-tabs">
|
||||
{chartDataResult.map((res, index) => (
|
||||
<Tabs.TabPane tab={t('Results %s', index + 1)} key={index}>
|
||||
<PaginationContainer>
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ def create_slices(tbl: SqlaTable) -> List[Slice]:
|
|||
viz_type="mixed_timeseries",
|
||||
metrics=["sum__num"],
|
||||
groupby=["gender"],
|
||||
metrics_b=["count"],
|
||||
metrics_b=["sum__num"],
|
||||
groupby_b=["state"],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ PRESTO_POLL_INTERVAL = 0.1
|
|||
HIVE_POLL_INTERVAL = 0.1
|
||||
|
||||
SQL_MAX_ROW = 10000
|
||||
SQLLAB_CTAS_NO_LIMIT = True # SQL_MAX_ROW will not take affect for the CTA queries
|
||||
SQLLAB_CTAS_NO_LIMIT = True # SQL_MAX_ROW will not take effect for the CTA queries
|
||||
FEATURE_FLAGS = {
|
||||
**FEATURE_FLAGS,
|
||||
"foo": "bar",
|
||||
|
|
@ -71,6 +71,7 @@ FEATURE_FLAGS = {
|
|||
"ALERT_REPORTS": True,
|
||||
"DASHBOARD_NATIVE_FILTERS": True,
|
||||
"DRILL_TO_DETAIL": True,
|
||||
"DRILL_BY": True,
|
||||
"HORIZONTAL_FILTER_BAR": True,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue