drilltodetail.test.ts 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import { waitForChartLoad } from 'cypress/utils';
  20. import { SUPPORTED_CHARTS_DASHBOARD } from 'cypress/utils/urls';
  21. import {
  22. openTopLevelTab,
  23. SUPPORTED_TIER1_CHARTS,
  24. SUPPORTED_TIER2_CHARTS,
  25. } from './utils';
  26. function interceptSamples() {
  27. cy.intercept(`**/datasource/samples*`).as('samples');
  28. }
  29. function openModalFromMenu(chartType: string) {
  30. interceptSamples();
  31. cy.get(
  32. `[data-test-viz-type='${chartType}'] [aria-label='More Options']`,
  33. ).click();
  34. cy.get('.ant-dropdown')
  35. .not('.ant-dropdown-hidden')
  36. .find("[role='menu'] [role='menuitem']")
  37. .eq(5)
  38. .should('contain', 'Drill to detail')
  39. .click();
  40. cy.wait('@samples');
  41. }
  42. function drillToDetail(targetMenuItem: string) {
  43. interceptSamples();
  44. cy.get('.ant-dropdown')
  45. .not('.ant-dropdown-hidden')
  46. .first()
  47. .find("[role='menu'] [role='menuitem']")
  48. .contains(new RegExp(`^${targetMenuItem}$`))
  49. .first()
  50. .trigger('keydown', { keyCode: 13, which: 13, force: true });
  51. cy.getBySel('metadata-bar').should('be.visible');
  52. cy.wait('@samples');
  53. }
  54. const drillToDetailBy = (targetDrill: string) => {
  55. interceptSamples();
  56. cy.get('.ant-dropdown:not(.ant-dropdown-hidden)')
  57. .should('be.visible')
  58. .find("[role='menu'] [role='menuitem']")
  59. .contains(/^Drill to detail by$/)
  60. .trigger('mouseover', { force: true });
  61. cy.get(
  62. '.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-submenu-hidden) [data-test="drill-to-detail-by-submenu"]',
  63. )
  64. .should('be.visible')
  65. .find('[role="menuitem"]')
  66. .then($el => {
  67. cy.wrap($el)
  68. .contains(new RegExp(`^${targetDrill}$`))
  69. .trigger('keydown', { keyCode: 13, which: 13, force: true });
  70. });
  71. cy.getBySel('metadata-bar').should('be.visible');
  72. return cy.wait('@samples');
  73. };
  74. function closeModal() {
  75. cy.get('body').then($body => {
  76. if ($body.find('[data-test="close-drilltodetail-modal"]').length) {
  77. cy.getBySel('close-drilltodetail-modal').click({ force: true });
  78. }
  79. });
  80. }
  81. function testTimeChart(vizType: string) {
  82. interceptSamples();
  83. cy.get(`[data-test-viz-type='${vizType}'] canvas`).then($canvas => {
  84. cy.wrap($canvas).scrollIntoView();
  85. cy.wrap($canvas).trigger('mousemove', 85, 93);
  86. cy.wrap($canvas).rightclick(85, 93);
  87. drillToDetailBy('Drill to detail by 1965');
  88. cy.getBySel('filter-val').should('contain', '1965');
  89. closeModal();
  90. cy.wrap($canvas).scrollIntoView();
  91. cy.wrap($canvas).trigger('mousemove', 85, 93);
  92. cy.wrap($canvas).rightclick(85, 93);
  93. drillToDetailBy('Drill to detail by boy');
  94. cy.getBySel('filter-val').should('contain', 'boy');
  95. closeModal();
  96. cy.wrap($canvas).scrollIntoView();
  97. cy.wrap($canvas).trigger('mousemove', 85, 93);
  98. cy.wrap($canvas).rightclick(85, 93);
  99. drillToDetailBy('Drill to detail by all');
  100. cy.getBySel('filter-val').first().should('contain', '1965');
  101. cy.getBySel('filter-val').eq(1).should('contain', 'boy');
  102. closeModal();
  103. });
  104. }
  105. // TODO fix this test, it has issues with autoscrolling and the locked title
  106. // flakes intricately when the righClick is obstructed by the title.
  107. // Tried many option around scrollIntoView, force, etc. but no luck.
  108. describe.skip('Drill to detail modal', () => {
  109. beforeEach(() => {
  110. closeModal();
  111. });
  112. describe('Tier 1 charts', () => {
  113. before(() => {
  114. cy.visit(SUPPORTED_CHARTS_DASHBOARD);
  115. openTopLevelTab('Tier 1');
  116. SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
  117. });
  118. describe('Modal actions', () => {
  119. it('opens the modal from the context menu', () => {
  120. openModalFromMenu('big_number_total');
  121. cy.get("[role='dialog'] .draggable-trigger").should(
  122. 'contain',
  123. 'Drill to detail: Big Number',
  124. );
  125. });
  126. it('refreshes the data', () => {
  127. openModalFromMenu('big_number_total');
  128. // move to the last page
  129. cy.get('.ant-pagination-item').eq(5).click();
  130. // skips error on pagination
  131. cy.on('uncaught:exception', () => false);
  132. cy.wait('@samples');
  133. // reload
  134. cy.get("[aria-label='Reload']").click();
  135. cy.wait('@samples');
  136. // make sure it started back from first page
  137. cy.get('.ant-pagination-item-active').should('contain', '1');
  138. });
  139. it('paginates', () => {
  140. openModalFromMenu('big_number_total');
  141. // checking the data
  142. cy.getBySel('row-count-label').should('contain', '75.7k rows');
  143. cy.get('.virtual-table-cell').should($rows => {
  144. expect($rows).to.contain('Amy');
  145. });
  146. // checking the paginated data
  147. cy.get('.ant-pagination-item')
  148. .should('have.length', 6)
  149. .should($pages => {
  150. expect($pages).to.contain('1');
  151. expect($pages).to.contain('1514');
  152. });
  153. cy.get('.ant-pagination-item').eq(4).click();
  154. // skips error on pagination
  155. cy.on('uncaught:exception', () => false);
  156. cy.wait('@samples');
  157. cy.get('.virtual-table-cell').should($rows => {
  158. expect($rows).to.contain('Kimberly');
  159. });
  160. // verify scroll top on pagination
  161. cy.getBySelLike('Number-modal').find('.virtual-grid').scrollTo(0, 200);
  162. cy.get('.virtual-grid').contains('Kim').should('not.be.visible');
  163. cy.get('.ant-pagination-item').eq(0).click();
  164. cy.get('.virtual-grid').contains('Aaron').should('be.visible');
  165. });
  166. });
  167. describe('Big number total', () => {
  168. it('opens the modal with no filters', () => {
  169. interceptSamples();
  170. // opens the modal by clicking on the number on the chart
  171. cy.get(
  172. "[data-test-viz-type='big_number_total'] .header-line",
  173. ).scrollIntoView();
  174. cy.get(
  175. "[data-test-viz-type='big_number_total'] .header-line",
  176. ).rightclick();
  177. drillToDetail('Drill to detail');
  178. cy.getBySel('filter-val').should('not.exist');
  179. });
  180. });
  181. describe('Big number with trendline', () => {
  182. it('opens the modal with the correct data', () => {
  183. interceptSamples();
  184. // opens the modal by clicking on the number
  185. cy.get(
  186. "[data-test-viz-type='big_number'] .header-line",
  187. ).scrollIntoView();
  188. cy.get("[data-test-viz-type='big_number'] .header-line").rightclick();
  189. drillToDetail('Drill to detail');
  190. cy.getBySel('filter-val').should('not.exist');
  191. closeModal();
  192. // opens the modal by clicking on the trendline
  193. cy.get("[data-test-viz-type='big_number'] canvas").then($canvas => {
  194. cy.wrap($canvas).scrollIntoView();
  195. cy.wrap($canvas).trigger('mousemove', 1, 14);
  196. cy.wrap($canvas).rightclick(1, 14);
  197. drillToDetailBy('Drill to detail by 1965');
  198. // checking the filter
  199. cy.getBySel('filter-val').should('contain', '1965');
  200. });
  201. });
  202. });
  203. describe('Table', () => {
  204. it('opens the modal with the correct filters', () => {
  205. interceptSamples();
  206. // focus on table first to trigger browser scroll
  207. cy.get("[data-test-viz-type='table']").contains('boy').rightclick();
  208. cy.wait(500);
  209. cy.get("[data-test-viz-type='table']").contains('boy').scrollIntoView();
  210. cy.get("[data-test-viz-type='table']").contains('boy').rightclick();
  211. drillToDetailBy('Drill to detail by boy');
  212. cy.getBySel('filter-val').should('contain', 'boy');
  213. closeModal();
  214. // focus on table first to trigger browser scroll
  215. cy.get("[data-test-viz-type='table']").contains('girl').rightclick();
  216. cy.wait(500);
  217. cy.get("[data-test-viz-type='table']").scrollIntoView();
  218. cy.get("[data-test-viz-type='table']").contains('girl').rightclick();
  219. drillToDetailBy('Drill to detail by girl');
  220. cy.getBySel('filter-val').should('contain', 'girl');
  221. });
  222. });
  223. describe('Pivot Table V2', () => {
  224. it('opens the modal with the correct filters', () => {
  225. interceptSamples();
  226. cy.get("[data-test-viz-type='pivot_table_v2']").scrollIntoView();
  227. cy.get("[data-test-viz-type='pivot_table_v2']")
  228. .find('[role="gridcell"]')
  229. .first()
  230. .rightclick();
  231. drillToDetailBy('Drill to detail by boy');
  232. cy.getBySel('filter-val').should('contain', 'boy');
  233. closeModal();
  234. cy.get("[data-test-viz-type='pivot_table_v2']").scrollIntoView();
  235. cy.get("[data-test-viz-type='pivot_table_v2']")
  236. .find('[role="gridcell"]')
  237. .first()
  238. .rightclick();
  239. drillToDetailBy('Drill to detail by CA');
  240. cy.getBySel('filter-val').should('contain', 'CA');
  241. closeModal();
  242. cy.get("[data-test-viz-type='pivot_table_v2']").scrollIntoView();
  243. cy.get("[data-test-viz-type='pivot_table_v2']")
  244. .find('[role="gridcell"]')
  245. .eq(3)
  246. .rightclick();
  247. drillToDetailBy('Drill to detail by girl');
  248. cy.getBySel('filter-val').should('contain', 'girl');
  249. closeModal();
  250. cy.get("[data-test-viz-type='pivot_table_v2']").scrollIntoView();
  251. cy.get("[data-test-viz-type='pivot_table_v2']")
  252. .find('[role="gridcell"]')
  253. .eq(3)
  254. .rightclick();
  255. drillToDetailBy('Drill to detail by FL');
  256. cy.getBySel('filter-val').should('contain', 'FL');
  257. closeModal();
  258. cy.get("[data-test-viz-type='pivot_table_v2']").scrollIntoView();
  259. cy.get("[data-test-viz-type='pivot_table_v2']")
  260. .find('[role="gridcell"]')
  261. .eq(3)
  262. .rightclick();
  263. drillToDetailBy('Drill to detail by all');
  264. cy.getBySel('filter-val').first().should('contain', 'girl');
  265. cy.getBySel('filter-val').eq(1).should('contain', 'FL');
  266. });
  267. });
  268. describe('Line Chart', () => {
  269. it('opens the modal with the correct filters', () => {
  270. testTimeChart('echarts_timeseries_line');
  271. });
  272. });
  273. describe.skip('Bar Chart', () => {
  274. it('opens the modal with the correct filters', () => {
  275. interceptSamples();
  276. cy.get("[data-test-viz-type='echarts_timeseries_bar'] canvas").then(
  277. $canvas => {
  278. cy.wrap($canvas).scrollIntoView();
  279. cy.wrap($canvas).rightclick(70, 100);
  280. drillToDetailBy('Drill to detail by 1965');
  281. cy.getBySel('filter-val').should('contain', '1965');
  282. closeModal();
  283. cy.wrap($canvas).scrollIntoView();
  284. cy.wrap($canvas).rightclick(70, 100);
  285. drillToDetailBy('Drill to detail by boy');
  286. cy.getBySel('filter-val').should('contain', 'boy');
  287. closeModal();
  288. cy.wrap($canvas).scrollIntoView();
  289. cy.wrap($canvas).rightclick(70, 100);
  290. drillToDetailBy('Drill to detail by all');
  291. cy.getBySel('filter-val').first().should('contain', '1965');
  292. cy.getBySel('filter-val').eq(1).should('contain', 'boy');
  293. closeModal();
  294. cy.wrap($canvas).scrollIntoView();
  295. cy.wrap($canvas).rightclick(72, 200);
  296. drillToDetailBy('Drill to detail by girl');
  297. cy.getBySel('filter-val').should('contain', 'girl');
  298. },
  299. );
  300. });
  301. });
  302. describe.skip('Area Chart', () => {
  303. it('opens the modal with the correct filters', () => {
  304. testTimeChart('echarts_area');
  305. });
  306. });
  307. describe('Scatter Chart', () => {
  308. it('opens the modal with the correct filters', () => {
  309. testTimeChart('echarts_timeseries_scatter');
  310. });
  311. });
  312. describe('Pie', () => {
  313. it('opens the modal with the correct filters', () => {
  314. interceptSamples();
  315. // opens the modal by clicking on the slice of the Pie chart
  316. cy.get("[data-test-viz-type='pie'] canvas").then($canvas => {
  317. cy.wrap($canvas).scrollIntoView();
  318. cy.wrap($canvas).rightclick(130, 150);
  319. drillToDetailBy('Drill to detail by girl');
  320. cy.getBySel('filter-val').should('contain', 'girl');
  321. closeModal();
  322. cy.wrap($canvas).scrollIntoView();
  323. cy.wrap($canvas).rightclick(230, 190);
  324. drillToDetailBy('Drill to detail by boy');
  325. cy.getBySel('filter-val').should('contain', 'boy');
  326. });
  327. });
  328. });
  329. describe.skip('World Map', () => {
  330. it('opens the modal with the correct filters', () => {
  331. interceptSamples();
  332. cy.get("[data-test-viz-type='world_map'] svg").then($canvas => {
  333. cy.wrap($canvas).scrollIntoView();
  334. cy.wrap($canvas).rightclick(70, 150);
  335. drillToDetailBy('Drill to detail by USA');
  336. cy.getBySel('filter-val').should('contain', 'USA');
  337. closeModal();
  338. });
  339. cy.get("[data-test-viz-type='world_map'] svg").then($canvas => {
  340. cy.wrap($canvas).scrollIntoView();
  341. cy.wrap($canvas).rightclick(200, 140);
  342. drillToDetailBy('Drill to detail by SRB');
  343. cy.getBySel('filter-val').should('contain', 'SRB');
  344. });
  345. });
  346. });
  347. });
  348. describe('Tier 2 charts', () => {
  349. before(() => {
  350. cy.visit(SUPPORTED_CHARTS_DASHBOARD);
  351. openTopLevelTab('Tier 2');
  352. SUPPORTED_TIER2_CHARTS.forEach(waitForChartLoad);
  353. });
  354. describe('Modal actions', () => {
  355. it('clears filters', () => {
  356. interceptSamples();
  357. // opens the modal by clicking on the box on the chart
  358. cy.get("[data-test-viz-type='box_plot'] canvas").then($canvas => {
  359. const canvasWidth = $canvas.width() || 0;
  360. const canvasHeight = $canvas.height() || 0;
  361. const canvasCenterX = canvasWidth / 3 + 15;
  362. const canvasCenterY = (canvasHeight * 5) / 6;
  363. cy.wrap($canvas).scrollIntoView();
  364. cy.wrap($canvas).rightclick(canvasCenterX, canvasCenterY, {
  365. force: true,
  366. });
  367. drillToDetailBy('Drill to detail by boy');
  368. // checking the filter
  369. cy.getBySel('filter-val').should('contain', 'boy');
  370. cy.getBySel('row-count-label').should('contain', '39.2k rows');
  371. cy.get('.ant-pagination-item')
  372. .should('have.length', 6)
  373. .then($pages => {
  374. expect($pages).to.contain('1');
  375. expect($pages).to.contain('785');
  376. });
  377. // close the filter and test that data was reloaded
  378. cy.getBySel('filter-col').find("[aria-label='Close']").click();
  379. cy.wait('@samples');
  380. cy.getBySel('row-count-label').should('contain', '75.7k rows');
  381. cy.get('.ant-pagination-item-active').should('contain', '1');
  382. cy.get('.ant-pagination-item')
  383. .should('have.length', 6)
  384. .then($pages => {
  385. expect($pages).to.contain('1');
  386. expect($pages).to.contain('1514');
  387. });
  388. });
  389. });
  390. });
  391. describe('Box plot', () => {
  392. it('opens the modal with the correct filters', () => {
  393. interceptSamples();
  394. cy.get("[data-test-viz-type='box_plot'] canvas").then($canvas => {
  395. cy.wrap($canvas).scrollIntoView();
  396. cy.wrap($canvas).trigger('mousemove', 135, 275);
  397. cy.wrap($canvas).rightclick(135, 275);
  398. drillToDetailBy('Drill to detail by boy');
  399. cy.getBySel('filter-val').should('contain', 'boy');
  400. closeModal();
  401. cy.wrap($canvas).scrollIntoView();
  402. cy.wrap($canvas).trigger('mousemove', 270, 280);
  403. cy.wrap($canvas).rightclick(270, 280);
  404. drillToDetailBy('Drill to detail by girl');
  405. cy.getBySel('filter-val').should('contain', 'girl');
  406. });
  407. });
  408. });
  409. describe('Generic Chart', () => {
  410. it('opens the modal with the correct filters', () => {
  411. testTimeChart('echarts_timeseries');
  412. });
  413. });
  414. describe('Smooth Chart', () => {
  415. it('opens the modal with the correct filters', () => {
  416. testTimeChart('echarts_timeseries_smooth');
  417. });
  418. });
  419. describe('Step Line Chart', () => {
  420. it('opens the modal with the correct filters', () => {
  421. testTimeChart('echarts_timeseries_step');
  422. });
  423. });
  424. describe('Funnel Chart', () => {
  425. it('opens the modal with the correct filters', () => {
  426. interceptSamples();
  427. cy.get("[data-test-viz-type='funnel'] canvas").then($canvas => {
  428. cy.wrap($canvas).scrollIntoView();
  429. cy.wrap($canvas).rightclick(170, 90);
  430. drillToDetailBy('Drill to detail by boy');
  431. cy.getBySel('filter-val').should('contain', 'boy');
  432. closeModal();
  433. cy.wrap($canvas).scrollIntoView();
  434. cy.wrap($canvas).rightclick(190, 250);
  435. drillToDetailBy('Drill to detail by girl');
  436. cy.getBySel('filter-val').should('contain', 'girl');
  437. });
  438. });
  439. });
  440. describe('Gauge Chart', () => {
  441. it('opens the modal with the correct filters', () => {
  442. interceptSamples();
  443. cy.get("[data-test-viz-type='gauge_chart'] canvas").then($canvas => {
  444. cy.wrap($canvas).scrollIntoView();
  445. cy.wrap($canvas).rightclick(135, 95);
  446. drillToDetailBy('Drill to detail by boy');
  447. cy.getBySel('filter-val').should('contain', 'boy');
  448. closeModal();
  449. cy.wrap($canvas).scrollIntoView();
  450. cy.wrap($canvas).rightclick(95, 135);
  451. drillToDetailBy('Drill to detail by girl');
  452. cy.getBySel('filter-val').should('contain', 'girl');
  453. });
  454. });
  455. });
  456. describe('Mixed Chart', () => {
  457. it('opens the modal with the correct filters', () => {
  458. testTimeChart('mixed_timeseries');
  459. });
  460. });
  461. describe.skip('Radar Chart', () => {
  462. it('opens the modal with the correct filters', () => {
  463. interceptSamples();
  464. cy.get("[data-test-viz-type='radar'] canvas").then($canvas => {
  465. cy.wrap($canvas).scrollIntoView();
  466. cy.wrap($canvas).rightclick(180, 45);
  467. drillToDetailBy('Drill to detail by boy');
  468. cy.getBySel('filter-val').should('contain', 'boy');
  469. closeModal();
  470. cy.wrap($canvas).scrollIntoView();
  471. cy.wrap($canvas).rightclick(180, 85);
  472. drillToDetailBy('Drill to detail by girl');
  473. cy.getBySel('filter-val').should('contain', 'girl');
  474. });
  475. });
  476. });
  477. describe('Treemap', () => {
  478. it('opens the modal with the correct filters', () => {
  479. interceptSamples();
  480. cy.get("[data-test-viz-type='treemap_v2'] canvas").then($canvas => {
  481. cy.wrap($canvas).scrollIntoView();
  482. cy.wrap($canvas).rightclick(100, 30);
  483. drillToDetailBy('Drill to detail by boy');
  484. cy.getBySel('filter-val').should('contain', 'boy');
  485. closeModal();
  486. cy.wrap($canvas).scrollIntoView();
  487. cy.wrap($canvas).rightclick(150, 250);
  488. drillToDetailBy('Drill to detail by girl');
  489. cy.getBySel('filter-val').should('contain', 'girl');
  490. });
  491. });
  492. });
  493. });
  494. });