github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/cypress/integration/webapp/e2e.ts (about) 1 // Following tests should have NO mocking involved. 2 // The objective involve validating server/webapp interaction is working correctly 3 4 import * as moment from 'moment'; 5 6 function randomName() { 7 const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 8 const num = 5; 9 10 return Array(num) 11 .fill(0) 12 .map(() => letters.substr(Math.floor(Math.random() * num + 1), 1)) 13 .join(''); 14 } 15 16 // assume this is probably the first app when ordered alphabetically 17 const firstApp = '0'; 18 19 describe('E2E Tests', () => { 20 // TODO: 21 // instead of generating a new application 22 // delete the old one? 23 let appName = ''; 24 // use a fixed time IN THE DAY so that the hours in the timeline are always the same 25 const t0 = moment().startOf('day').unix(); 26 const t1 = moment().startOf('day').add(3, 'minutes').unix(); 27 const t2 = moment().startOf('day').add(5, 'minutes').unix(); 28 const t3 = moment().startOf('day').add(6, 'minutes').unix(); 29 const t4 = moment().startOf('day').add(10, 'minutes').unix(); 30 31 before(() => { 32 appName = randomName(); 33 34 // populate the db with 2 items 35 // 36 // it's important that they are recent 37 // otherwise the database may just drop them 38 // if they are older than the retention date 39 40 cy.request({ 41 method: 'POST', 42 url: `/ingest?name=${firstApp}&sampleRate=100&from=${t1}&until=${t1}`, 43 body: 'foo;bar 100', 44 }); 45 46 cy.request({ 47 method: 'POST', 48 url: `/ingest?name=${appName}&sampleRate=100&from=${t1}&until=${t1}`, 49 body: 'foo;bar 100', 50 }); 51 52 cy.request({ 53 method: 'POST', 54 url: `/ingest?name=${appName}&sampleRate=100&from=${t3}&until=${t3}`, 55 body: 'foo;bar;baz 10', 56 }); 57 }); 58 59 it('tests single view', () => { 60 const params = new URLSearchParams(); 61 params.set('query', appName); 62 params.set('from', t0); 63 params.set('until', t4); 64 65 cy.visit(`/?${params.toString()}`); 66 67 cy.waitForFlamegraphToRender(); 68 }); 69 70 it('tests /comparison view', () => { 71 const params = new URLSearchParams(); 72 params.set('query', appName); 73 params.set('from', t0); 74 params.set('until', t4); 75 params.set('leftFrom', t0); 76 params.set('leftUntil', t2); 77 params.set('rightFrom', t2); 78 params.set('rightTo', t4); 79 80 cy.visit(`/comparison?${params.toString()}`); 81 82 const findFlamegraph = (n: number) => { 83 const query = `> :nth-child(${n})`; 84 85 return cy.findByTestId('comparison-container').find(query); 86 }; 87 88 // flamegraph 1 (the left one) 89 findFlamegraph(1).waitForFlamegraphToRender(); 90 91 // flamegraph 2 (the right one) 92 findFlamegraph(2).waitForFlamegraphToRender(); 93 }); 94 95 it('tests /explore view', () => { 96 const params = new URLSearchParams(); 97 params.set('query', appName); 98 params.set('from', t0); 99 params.set('until', t4); 100 101 cy.visit('/'); 102 cy.findByTestId('collapse-sidebar').click(); 103 cy.findByTestId('sidebar-explore-page').click(); 104 105 cy.findByTestId('explore-header'); 106 cy.findByTestId('timeline-explore-page'); 107 cy.findByTestId('explore-table'); 108 }); 109 110 it('works with standalone view', () => { 111 const params = new URLSearchParams(); 112 params.set('query', appName); 113 params.set('from', t0); 114 params.set('until', t4); 115 params.set('leftFrom', t0); 116 params.set('leftUntil', t2); 117 params.set('rightFrom', t2); 118 params.set('rightTo', t4); 119 params.set('format', 'html'); 120 121 cy.visit(`/render?${params.toString()}`); 122 cy.findByTestId('flamegraph-canvas'); 123 }); 124 125 // This is tested as an e2e test 126 // Since the list of app names comes populated from the database 127 it('sets the first app as the query if nothing is set', () => { 128 cy.visit('/'); 129 130 cy.location().should((loc) => { 131 const params = new URLSearchParams(loc.search); 132 expect(params.get('query')).to.eq(`${firstApp}{}`); 133 }); 134 }); 135 });