From 8d6f1711975514823c0a9da8ba7540b6be85658b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Rinc=C3=B3n=20Blanco?= Date: Sun, 4 Sep 2022 17:31:36 +0200 Subject: [PATCH] Cypress test to open all panes (#3953) --- .github/workflows/test-frontend.yml | 1 + cypress/.gitignore | 3 - cypress/integration/frontend-testing.js | 124 +++++++++++++++++++++--- cypress/integration/functionality.js | 10 ++ cypress/plugins/index.js | 22 +++++ cypress/support/commands.js | 25 +++++ cypress/support/index.js | 17 ++++ cypress/support/utils.js | 19 ++++ static/tests/_all.js | 1 + views/index.pug | 4 +- views/popups/alert.pug | 2 +- views/templates/panes/codeEditor.pug | 6 +- views/templates/panes/compiler.pug | 8 +- 13 files changed, 215 insertions(+), 27 deletions(-) create mode 100644 cypress/integration/functionality.js create mode 100644 cypress/plugins/index.js create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/index.js create mode 100644 cypress/support/utils.js diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index c2e76c0e9..b15cc1564 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -17,3 +17,4 @@ jobs: with: start: npm run dev wait-on: 'http://localhost:10240' + config: screenshotOnRunFailure=false,video=false diff --git a/cypress/.gitignore b/cypress/.gitignore index 9bd9158e8..733b5fd67 100644 --- a/cypress/.gitignore +++ b/cypress/.gitignore @@ -1,5 +1,2 @@ -/fixtures -/plugins /screenshots -/support /videos diff --git a/cypress/integration/frontend-testing.js b/cypress/integration/frontend-testing.js index 58d72623d..45830749f 100644 --- a/cypress/integration/frontend-testing.js +++ b/cypress/integration/frontend-testing.js @@ -1,23 +1,119 @@ -function runFrontendTest(name) { - it(name, () => { - cy.window().then(win => { - return win.compilerExplorerFrontendTesting.run(name); +import {it} from 'mocha'; +import {assertNoConsoleOutput, stubConsoleOutput} from '../support/utils'; + +const PANE_DATA_MAP = { + executor: {name: 'Executor', selector: 'create-executor'}, + opt: {name: 'Opt Viewer', selector: 'view-optimization'}, + preprocessor: {name: 'Preprocessor', selector: 'view-pp'}, + ast: {name: 'Ast Viewer', selector: 'view-ast'}, + llvmir: {name: 'LLVM IR', selector: 'view-ir'}, + pipeline: {name: 'Pipeline', selector: 'view-llvm-opt-pipeline'}, + device: {name: 'Device', selector: 'view-device'}, + mir: {name: 'MIR', selector: 'view-rustmir'}, + hir: {name: 'HIR', selector: 'view-rusthir'}, + macro: {name: 'Macro', selector: 'view-rustmacroexp'}, + core: {name: 'Core', selector: 'view-haskellCore'}, + stg: {name: 'STG', selector: 'view-haskellStg'}, + cmm: {name: 'Cmm', selector: 'view-haskellCmm'}, + dump: {name: 'Tree/RTL', selector: 'view-gccdump'}, + tree: {name: 'Tree', selector: 'view-gnatdebugtree'}, + debug: {name: 'Debug', selector: 'view-gnatdebug'}, + cfg: {name: 'Graph', selector: 'view-cfg'}, +}; + +describe('Individual pane testing', () => { + beforeEach(() => { + cy.visit('/', { + onBeforeLoad: win => { + stubConsoleOutput(win); + win.localStorage.clear(); + }, + }); + cy.get('[data-cy="new-compiler-dropdown-btn"]:visible').click(); + // Shows every pane button even if the compiler does not support it + cy.get('[data-cy="new-compiler-pane-dropdown"]:visible button').each($btn => { + $btn.prop('disabled', false).show(); }); }); -} -describe('Frontendtestresults', () => { - before(() => { - cy.visit('/'); + afterEach('Ensure no output in console', () => { + cy.window().then(win => { + assertNoConsoleOutput(); + win.localStorage.clear(); + }); }); - runFrontendTest('HelloWorld'); -}); + function addPaneOpenTest(paneData) { + it(paneData.name + ' pane', () => { + cy.get(`[data-cy="new-${paneData.selector}-btn"]:visible`).click(); + // Not the most consistent way, but the easiest one! + cy.get('span.lm_title:visible').contains(paneData.name); + }); + } -describe('Motd testing', () => { - before(() => { - cy.visit('/'); + addPaneOpenTest(PANE_DATA_MAP.executor); + addPaneOpenTest(PANE_DATA_MAP.opt); + addPaneOpenTest(PANE_DATA_MAP.preprocessor); + addPaneOpenTest(PANE_DATA_MAP.ast); + addPaneOpenTest(PANE_DATA_MAP.llvmir); + addPaneOpenTest(PANE_DATA_MAP.pipeline); + addPaneOpenTest(PANE_DATA_MAP.device); + addPaneOpenTest(PANE_DATA_MAP.mir); + addPaneOpenTest(PANE_DATA_MAP.hir); + addPaneOpenTest(PANE_DATA_MAP.macro); + addPaneOpenTest(PANE_DATA_MAP.core); + addPaneOpenTest(PANE_DATA_MAP.stg); + addPaneOpenTest(PANE_DATA_MAP.cmm); + addPaneOpenTest(PANE_DATA_MAP.dump); + addPaneOpenTest(PANE_DATA_MAP.tree); + addPaneOpenTest(PANE_DATA_MAP.debug); + // TODO: Bring back once #3899 lands + // addPaneOpenTest(PaneDataMap.cfg); + + it('Output pane', () => { + // Hide the dropdown + cy.get('[data-cy="new-compiler-dropdown-btn"]:visible').click(); + cy.get(`[data-cy="new-output-pane-btn"]:visible`).click(); + cy.get('span.lm_title:visible').contains('Output'); + }); + + it('Conformance view pane', () => { + // First, hide the dropdown + cy.get('[data-cy="new-compiler-dropdown-btn"]:visible').click(); + cy.get('[data-cy="new-editor-dropdown-btn"]:visible').click(); + cy.get('[data-cy="new-conformance-btn"]:visible').click(); + cy.get('span.lm_title:visible').contains('Conformance'); + }); +}); + +describe('Known good state test', () => { + beforeEach(() => { + cy.visit( + '/#z:OYLghAFBqd5TB8IAsQGMD2ATApgUWwEsAXTAJwBoiQIAzIgG1wDsBDAW1xAHIBGHpTqYWJAMro2zEHwAsQkSQCqAZ1wAFAB68ADIIBWMyozYtQ6AKQAmAELWblNc3QkiI2q2wBhTIwCuHCwgVpSeADJELLgAcgEARrjkIPIADpgqpG4sPv6BwZRpGa4iEVGxHAlJ8k64LlliJGzkJDkBQSE1dSINTSSlMfGJyY6Nza15HaN9kQMVQ7IAlI6YfuTo3DwA9JsA1AAqAJ4puDsHK%2BQ7WHg7KIm4lDsUO4yYbNg7pju4mpwpzAB0Fh0AEFIiQdioAI5%2BJq4CBgnYsAILHYWADsdhBO2xO3IuBIqxYiICOwAVMSOBYAMyY4HogAiPCWjF4AFZBEEeHpKJheF57PYIed1qirFSBJQSLomUsANYgVk6Yy8WSCDgKpWc7m8niCFQgJVSrlMyhwWBoLAsYTkDimdbUDzEMjkIjYIwmMwASTdlls9mWq3WvG2%2ByOJzOq0uOBOtzxDyeLzeHyJ31%2BAKBoNEEOhsPhWaRHBR6NpONx%2BMJFLJFOptIZJpZPHZlC1gh1PitFFtLBFADUiLgAO6JHYQQikJ7WcULQRGvQLJa3N5DCDMlVq4Ks5vSnm8PUGyXSpZmqBoch%2BFQkFBEKg0CBYDgpJiJaKcDbAAW2HZ4OhsPyMEiCLgToUK6RiGHwAZrBsIaHMcpznFG1yxvcjwXIm7yfKmD7piCCJQjCeJ5uCBZFhiGalniBLkESBZVgWNYZnWkp4rgoH8PWbIctuOoAErnuCAASno8TsfaDsO75%2Bp%2B36/v%2BI5js6orig8PgPk%2BFyTnw04Hsa86UIueBJCuyo8KqlDqlYm4tjuuqOPus4ypQ8qyEqDZUlxxo2TOh6mogx6oBgmBqcwN60Pej4hSAwAyX%2BJBCEwJCJPqEBxNucSRE0By8BK95cKIADyLCMFlnl4F2wDSKV161K4ABuuD6p53y1H4iXZYIYK4A23KMEQcTkJlPh4NuJAuuq7FLHQJjACoYkDvlxychKwiiBIUjcHICiiKoGjaJ54HGKY5gfg4vVxPqkBLJgKTFCwjV6l1NVZB4LDeL4bRGOEMzlJURiFJkIjjEEEH/bd/Q/UMEGdLdPRjO9eRQ49XQsLD0xlIMSRQ1MQNGBevTgxjMhLCowobcxuAbBKA6mCQC0kJ6HY%2BQ2TbWTqkl2NJuA/rFI78lJDg7ApE5ihBOyqRFw6adpDl6QZy5yhqJlmeqipbp5Op7oaPn%2BWgKwkCkrUOneQUS%2BQL5cLw7OCjF/6AcBLpuhBK3iJI0ibc7O1aNuB0DgNKTtaujYedqvD5a1BvgpgdA7FbnPc3JEDi%2BpSlad5ukLrgS5GYHysbmrIe2fqWu6b5yCnvxtroOQmDfCkRvhep5tvidX5c7JAGhPboEQQdJOBtBuyweGCFXDGdzxmhrwYSmPzYbggK4Vm%2BG5giJGomRWI4pRFa0eS9E0oxaKMuTrFuhNJks9xvB8ReOwALJsFXmCC5oKSmBkIiif2Q4XLHNit/HcEo57YpxUibZOUs05zgzlnWgOd1yWXzq2Xcdli7QKciAAAbK5Xg7kkFeR0ug%2BUVI0T/DFGKNErIACcaIqF8D4FYKwaITJWHXHwHQmor62RlqXWAfl%2BFlxAM1dArUKBGyaDNdQpgupiBQJgAcS1BANxMLdKRURGCyPkdZZRQxopt1ipQHR5Aw7iDkQo7cwjgTkBmig4RDRiCckEM7Nabt5AezUF7fa7ojoYBOsYPqF1jLXVuvdSCQYsYOLUTIsxiiT7tUoL7Ng/tz7M2Dsgng%2BBNAtUUn/AB7deZ%2BMFiAyBhDHJy2zhg1WDZc6INZigoupSjx%2BTQMAdgJA8BxD8MAUaFN67gJCk3S2LcbYdyAuOB2YFcak2DIPMM8FIyjxuOPVCzwp7Ji%2BLPP488Mx4RzIRVeyJ14li3uWailY94BAYiCJiPTT4BwvmkmyABxaIwI9g7HpLgTpwB9gsS/uJX%2Bwz9EJyFhpEWYDgqSxFtLQ8MDDJwKVggqyXDNaNN4SeEA14%2BmQrNq%2BIZ/M8mxTtuM7ulBe7TK2LMuCEYLiLOQhPVZSZMKbJwpmcEy99n5kOcWciJyqI0RJBcykB9rlHxnCxNiAhA6X3VrwMIYQex3x2MJf5P8Y5AsAfJYp4Kxb9KhVOKBZTM7wuMtUpF%2BCNaoLRTrEAKA2AqFlF1RgPg4y3iMYMnguSRnEudKS8l/cZmhmpSPaMSy4wrPQusrCWyF5suzAROEBzCxHN5dibeZzd7VhFXSMVJ9JUcSDha3gTyBJeF1XiVVEkNX5OAeM0BuqcUpxhenfSxr5aIvMnnOphd7KwsqTgngeDu2GqacgZpIBgnYtNh6r1wLRld0dmSqZAbKVBuHgs0N9KI1rOZWmbZi92V7MTVy5NPLN5ptOQKjgdFLnZpuRKs%2BUqHlFp4HTStgKCUjK1XWzSELTZNpHXC9t8oqlrk7bUlFVqeE2taWwdpXyulTsbniz11aiWdxJYu/1UFA1D3mbSzdyyEw7pnnu2NuyE1EQpKRY5F7%2BXnKzbWXNtz83SseTqF5byPkIZ%2BXNKtn653fsUr%2Bht/6SkyyAxUs14HkWyp7Wgk0NrGCMFqhwOm6giDHF6lEOaRseAAFo6AsEwPp4gKhJDkGwPp2qUg/C4H0%2BwLgKgeDbndSh2dgDBBlSOswfTKgDgVF8I1bk2AAgpEM3%2BRg%2BmOA4D/JTH1IFF0MH/IkfTkRLRqGhKwVwUh9NvxUGoRqy1FAuI2m4xQns9rcjQMp1T6nNNdRmLp3uSNErYAAGJ%2BG7LdeprWgIMzwNoJUGQOlNAAOqukvBuQ0D77mpJffKxVOw30aa0zMd96qBOatrcJnVScQoAcaZJhF0mLKyYLqi6D467UOqdQ0YASGBnubQ7bDDvqsPLpw6uvDNLEJj3DcRplpG57kaXkeqja8z3Agopehj%2B8mPHxY4%2BgtMqC4lrLWIPYTyNseZraC%2Bt%2B39WpyO622BpqwNnZfZdvtIGB1DsgxJypsh/h8EwWz9nHP2fyAbKwzt7DOFyZHeim1KQ65uo9MAQznY4PxLGe9owyXErkH0%2BU4LTiSuuzK1tZQHiqsGCMEjubnEX3qDxCkau6wCtPBMRHTbHN/5fp28LZSomIHQsA6Tk1CsrBUJZ5z/3bOAAcHbKfDqg9rcd6A6APbdXq3FFtUNbfbgliZPcjDBKyMldgtUiDADg89diBQUAHAyOgIrJpCi0AAPo16G5QGvVeso6GJpr3GfWOucg5cekgCxeB5uR2xl9Ty/YoBxy9oB%2BOROE7BQakn5STsU67ZBhpV3BF4Bz/aW86%2BiBBlsnLxLCuNfrRkOV7auvvZt%2BcD1iAngcYQS%2BujOYmMCjpABtkeGwMX9FCyATJ/l%2BnrdDYwf7/7Iyoy/6/RYy9B34jD4zfSExaT95G6FrdqfIb4nB8Yfr26Eograou7T6HaM7z7k6mTmph4r4R6CI3aOrKZeAcAcCPbPjPZJ7ob76p5LpQwUowRzK/Z0pEaTxA4bJkY7Jg6UZJo0applj0aZrw6HyI6zYpLG7dro5ix0Fj7ME4E/p7Zx4EF9pEHwIyZU7h4tryhWCB4s5WD0KB6yAkKWHWFohUgmT06C7WoCLmggD2pxSx44ozrj4p5%2Bqfa75cHBobpIR8GMrTyCEg7CGHqiEnriHnqSE7yCqMayHioUysbPrdrAi3wYF27WyCZO4z6iz4Hia6FtpSaL6qxkG9olw2pngXgcBYpeHTpMFYHepvYH5p4cErpBHroEahEA78ERHRqsoUYrxxEpoJHppXo3rCoI5pF3IKHIFcI3zgh3wqq5G448yFEE7aGlEtp6Eh7BCYL/A6BihUh0KB4MKB6YKsiyBULB7VEKajpuHADoDoChYPhGxV5uYJ5bGvY/Fx6kpV6sHAmG6F5vDYB4gFZ0wF4ShSCMCwnuCF5xAvDoCygqBImxK/HNzqEdx4CNBMCYk3Rwl%2BFJZH6uLa6VbbgtLvGfFi5vz0hhYX4QTaasCYBYnxIDTzQknIkSjNCMBMkPjbjQxARSIFYIrQzPQ36vTQEP6zAQFf5v7QGgw/5wF/6IxX71BAG5Cf5SmAGwGP6Kl4xwy6m4xTDgGQzEy9Rqa8mxJ4wkDEk9aF63JCnJLcjgkSh%2BCuicmF61TXROmkmD5KFeBlp7AsSbA8R7BhBqFtEFGT5aGNr7HoKHGnbBBUj/A0Js46BXGB5oh8BUiyCKghBPEk7yh8CkL5kWGyCB5UKYLVm1n1mOHsYoKM7yj1n/BoiYJdlWAuRWA5l5lojc68C87qj86GGM484tncJ9r1TkAfxBCyBAA', + { + onBeforeLoad: win => { + stubConsoleOutput(win); + win.localStorage.clear(); + }, + }, + ); + }) + + afterEach('Ensure no output in console', () => { + cy.window().then(win => { + assertNoConsoleOutput(); + win.localStorage.clear(); + }); + }); + + it('Correctly loads the page for a state with every pane active', () => { + for (const paneId in PANE_DATA_MAP) { + const pane = PANE_DATA_MAP[paneId]; + cy.get('span.lm_title:visible').contains(pane.name); + } + + cy.get('span.lm_title:visible').contains('Output'); + cy.get('span.lm_title:visible').contains('Conformance'); }); - runFrontendTest('motd'); }); diff --git a/cypress/integration/functionality.js b/cypress/integration/functionality.js new file mode 100644 index 000000000..db378f75d --- /dev/null +++ b/cypress/integration/functionality.js @@ -0,0 +1,10 @@ +import {runFrontendTest} from '../support/utils'; + + +describe('Motd testing', () => { + before(() => { + cy.visit('/'); + }); + + runFrontendTest('motd'); +}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 000000000..59b2bab6e --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,22 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..119ab03f7 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 000000000..185d654ec --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' diff --git a/cypress/support/utils.js b/cypress/support/utils.js new file mode 100644 index 000000000..80a0ed3ee --- /dev/null +++ b/cypress/support/utils.js @@ -0,0 +1,19 @@ +export function runFrontendTest(name) { + it(name, () => { + cy.window().then(win => { + return win.compilerExplorerFrontendTesting.run(name); + }); + }); +} + +export function stubConsoleOutput(win) { + cy.stub(win.console, 'log').as('consoleLog'); + cy.stub(win.console, 'warn').as('consoleWarn'); + cy.stub(win.console, 'error').as('consoleError'); +} + +export function assertNoConsoleOutput() { + cy.get('@consoleLog').should('not.be.called'); + cy.get('@consoleWarn').should('not.be.called'); + cy.get('@consoleError').should('not.be.called'); +} diff --git a/static/tests/_all.js b/static/tests/_all.js index 0a3a40fc7..8d1c9ce04 100644 --- a/static/tests/_all.js +++ b/static/tests/_all.js @@ -25,3 +25,4 @@ require('./frontend-testing'); require('./hello-world'); require('./motd'); +// require('./ui'); diff --git a/views/index.pug b/views/index.pug index 872301c0e..588f74421 100644 --- a/views/index.pug +++ b/views/index.pug @@ -20,7 +20,7 @@ block prepend content span.dropdown-icon.fa.fa-list-alt | Tree (IDE Mode) li.nav-item.dropdown - button.btn.btn-light.nav-link.dropdown-toggle#moreDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") More + button.btn.btn-light.nav-link.dropdown-toggle#moreDropdown(role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="more-dropdown-btn") More div.dropdown-menu(aria-labelledby="moreDropdown") button.dropdown-item.btn#setting(data-target="#settings" data-toggle="modal") span.dropdown-icon.fas.fa-sliders-h @@ -29,7 +29,7 @@ block prepend content button.dropdown-item.btn#ui-brokenlink span.dropdown-icon.fas.fa-undo-alt | Reset UI layout - button.dropdown-item.btn#ui-reset + button.dropdown-item.btn#ui-reset(data-cy="reset-ui-btn") span.dropdown-icon.fas.fa-trash-alt | Reset code and UI layout button.dropdown-item.btn#ui-duplicate diff --git a/views/popups/alert.pug b/views/popups/alert.pug index ed6269152..b79ecfb3f 100644 --- a/views/popups/alert.pug +++ b/views/popups/alert.pug @@ -8,4 +8,4 @@ | × .modal-body .modal-footer - button.btn.btn-outline-primary(type="button" data-dismiss="modal") Close + button.btn.btn-outline-primary(type="button" data-dismiss="modal" data-cy="close-alert-btn") Close diff --git a/views/templates/panes/codeEditor.pug b/views/templates/panes/codeEditor.pug index a885177d9..9cc4e7a24 100644 --- a/views/templates/panes/codeEditor.pug +++ b/views/templates/panes/codeEditor.pug @@ -1,5 +1,5 @@ mixin newPaneButton(classId, text, title, label, icon) - button(class="dropdown-item btn btn-sm btn-light " + classId title=title) + button(class="dropdown-item btn btn-sm btn-light " + classId title=title data-cy="new-" + classId + "-btn") span(class="dropdown-icon " + icon) | #{text} @@ -10,10 +10,10 @@ mixin newPaneButton(classId, text, title, label, icon) button.btn.btn-sm.btn-light.load-save(title="Load or save text" aria-label="Load or save text") span.fa.fa-save span.hideable Save/Load - button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") + button.dropdown-toggle.btn.btn-sm.btn-light.add-pane(type="button" title="Add a new pane" aria-label="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-cy="new-editor-dropdown-btn") span.fa.fa-plus span.hideable Add new... - .dropdown-menu + .dropdown-menu(data-cy="new-editor-pane-dropdown") +newPaneButton("add-compiler", "Compiler", "Add a new compiler for this source", "New compiler", "fa fa-cogs") +newPaneButton("add-executor", "Execution Only", "Add a new executor for this source", "New executor", "fas fa-microchip") +newPaneButton("conformance", "Conformance View", "Add a new conformance view", "New conformance view", "fa fa-list") diff --git a/views/templates/panes/compiler.pug b/views/templates/panes/compiler.pug index 4afc6c623..b1fca3bb5 100644 --- a/views/templates/panes/compiler.pug +++ b/views/templates/panes/compiler.pug @@ -1,5 +1,5 @@ mixin newPaneButton(classId, text, title, icon) - button(class="dropdown-item btn btn-sm btn-light " + classId title=title) + button(class="dropdown-item btn btn-sm btn-light " + classId title=title data-cy="new-" + classId + "-btn") span(class="dropdown-icon " + icon) | #{text} @@ -40,10 +40,10 @@ mixin newPaneButton(classId, text, title, icon) span.fas.fa-book span.dp-text.hideable Libraries .btn-group.btn-group-sm(role="group") - button.btn.btn-sm.btn-light.dropdown-toggle.add-pane(type="button" title="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add new element for this compiler") + button.btn.btn-sm.btn-light.dropdown-toggle.add-pane(type="button" title="Add a new pane" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Add new element for this compiler" data-cy="new-compiler-dropdown-btn") span.fas.fa-plus span.hideable Add new... - .dropdown-menu.dropdown-menu-right.new-pane-dropdown + .dropdown-menu.dropdown-menu-right.new-pane-dropdown(data-cy="new-compiler-pane-dropdown") +newPaneButton("add-compiler", "Clone Compiler", "Clone this compiler window (click or drag)", "far fa-clone") +newPaneButton("create-executor", "Executor From This", "Create executor from this compiler", "fas fa-microchip") +newPaneButton("view-optimization", "Optimization", "Show optimization output", "fas fa-weight") @@ -75,7 +75,7 @@ mixin newPaneButton(classId, text, title, icon) .input-group-prepend button.btn.btn-sm.btn-light.clear-cache(title="Clear cache & recompile") span.fas.fa-redo - button.btn.btn-sm.btn-light.output-btn + button.btn.btn-sm.btn-light.output-btn(data-cy="new-output-pane-btn") span.fas.fa-receipt.status-text |  Output span.output-count