This commit is contained in:
2023-01-03 00:04:38 +00:00
commit 3f002872e3
925 changed files with 181049 additions and 0 deletions
@@ -0,0 +1,6 @@
{
"rules": {
"testing-library/await-async-utils": 0,
"testing-library/await-async-query": 0,
}
}
@@ -0,0 +1,13 @@
describe('App', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.visit('/');
cy.waitForSplashScreen();
});
it('should render the app', () => {
// dev: picking a random element that should display, in this case the 'File' menu dropdown
// eslint-disable-next-line testing-library/prefer-screen-queries
cy.findByText('File').should('exist');
});
});
@@ -0,0 +1,41 @@
describe('Dialogs: Confirm', () => {
/**
* TopBar uses the `ConfirmDialog` and `AlertDialog` components
* from the `Dialogs` plugin, but both are available for use by
* other plugins and components.
* The AlertDialog component is generally reserved for unxpected
* end user error messages, and hopefully not seen in normal use,
* so we do not currently test it here.
* Ref: plugin.dropzone.spec.js contains an E2E assertion for AlertDialog
* */
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('should close the Confirm Dialog via `x` button', () => {
cy.contains('File').click(); // File Menu
cy.contains('Import URL')
.trigger('mousemove')
.click()
.get('#input-import-url')
.should('be.visible')
.get('.close')
.click()
.get('#input-import-url')
.should('not.exist');
});
it('should close the Confirm Dialog via `Cancel` button', () => {
cy.contains('File').click(); // File Menu
cy.contains('Import URL')
.trigger('mousemove')
.click()
.get('#input-import-url')
.should('be.visible')
.get('.btn-secondary')
.click()
.get('#input-import-url')
.should('not.exist');
});
});
@@ -0,0 +1,46 @@
describe('Dropzone in Layout', () => {
describe('file uploads with dropzone', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
describe('when more than one file of an expected type is dropped', () => {
it('should inform the user that their file(s) were rejected', () => {
cy.get('[data-cy="dropzone"]')
.attachFile(['petstore-oas3.yaml', 'petstore-oas3.yaml'], { subjectType: 'input' })
.then(() => {
cy.get('.modal-title')
.should('contains.text', 'Uh oh, an error has occurred')
.get('.modal-body > div')
.should('contains.text', 'Sorry, there was an error processing your file')
// assert on AlertDialog interaction via `x` button'
.get('.close')
.click()
.get('.modal-title')
.should('not.exist');
});
});
});
describe('when one file of an expected type is dropped', () => {
it('should update the EditorPane and the EditorPreviewPane', () => {
/**
* subjectType: 'drag-n-drop' doesn't work correctly as it generates
* `dragleave` and then `dragenter` events (in that order), which manifests in always
* seeing the dropzone overlay. The goal of this test is to see when the
* file is uploaded that the editor content and rendered UI changes and
* this goal is satisfied.
*/
cy.get('[data-cy="dropzone"]').attachFile('petstore-oas3.yaml', {
subjectType: 'input',
});
// This assertion assumes change from non-OAS3 to OAS3, where a "badge" will exist for OAS3
cy.get('.version-stamp > .version').should('have.text', 'OAS3');
});
});
});
});
@@ -0,0 +1,62 @@
describe('Monaco Editor with Parser', () => {
const selectAllKeys = ['darwin'].includes(Cypress.platform) ? '{cmd}a' : '{ctrl}a';
beforeEach(() => {
cy.visitBlankPage();
cy.window().then((contentWindow) => {
// console.log already globally stubbed in cy support/commands
cy.spy(contentWindow.console, 'error').as('consoleError');
});
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('should not throw console.error when parsing empty string', () => {
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.click({ force: true })
.focused()
.type(selectAllKeys)
.clear();
cy.waitForContentPropagation();
cy.get('@consoleError').should('not.be.called');
cy.get('.monaco-editor .view-lines').should('contains.text', '');
});
it('should not throw console.error when parsing unsupported definition', () => {
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.click({ force: true })
.focused()
.type(selectAllKeys)
.type('randomapi: 1.0.0\n');
cy.waitForContentPropagation();
cy.get('@consoleError').should('not.be.called');
cy.get('.monaco-editor .view-lines').should('contains.text', 'randomapi');
});
it('should toggle between light and dark themes', () => {
// default dark
cy.get(':nth-child(2) > .swagger-editor__editor-pane-bar-control > .octicon-sun').should(
'be.visible'
);
cy.get('.swagger-editor__editor-monaco > .vs-dark ').should('exist');
// toggle to light
cy.get(':nth-child(2) > .swagger-editor__editor-pane-bar-control').click();
cy.get(':nth-child(2) > .swagger-editor__editor-pane-bar-control > .octicon-moon').should(
'be.visible'
);
cy.get('.swagger-editor__editor-monaco > .vs ').should('exist');
// toggle back to dark
cy.get(':nth-child(2) > .swagger-editor__editor-pane-bar-control').click();
cy.get(':nth-child(2) > .swagger-editor__editor-pane-bar-control > .octicon-sun').should(
'be.visible'
);
cy.get('.swagger-editor__editor-monaco > .vs-dark ').should('exist');
});
});
@@ -0,0 +1,40 @@
describe('EditorPersistencePlugin', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareOasGenerator();
});
it('should load definition with provided url prop', () => {
cy.prepareAsyncAPI();
cy.waitForSplashScreen();
cy.get('.monaco-editor .view-lines')
.should('contains.text', 'asyncapi')
.should('contains.text', '2.5.0');
});
it.skip('should reload while keeping text change from 2.5.0 to 2.4.0', () => {
cy.prepareAsyncAPI();
cy.waitForSplashScreen();
const moveToPosition = `{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}{rightArrow}`;
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.click({ force: true })
.focused()
.type(`${moveToPosition}{shift+rightArrow}4`);
cy.get('.monaco-editor .view-lines')
.should('contains.text', '2.4.0')
.should('not.contains.text', '2.5.0');
cy.waitForContentPropagation();
cy.reload();
cy.waitForSplashScreen();
cy.get('.monaco-editor .view-lines')
.should('contains.text', '2.4.0')
.should('not.contains.text', '2.5.0');
});
});
@@ -0,0 +1,26 @@
describe('Editor Preview Pane: AsyncAPI 2.x', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('displays API Design Systems', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('API Design Systems').trigger('mousemove').click();
cy.get('.title').contains('SmartBear API Guidelines').should('be.visible');
cy.get('.version-stamp > .version').should('be.visible').contains('ADS').should('be.visible');
});
it('hidden if not API Design Systems', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.get('.title').contains('SmartBear API Guidelines').should('not.exist');
cy.get('.version-stamp > .version').find('ADS').should('not.exist');
});
});
@@ -0,0 +1,26 @@
describe('Editor Preview Pane: AsyncAPI 2.x', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('displays AsyncAPI 2.x.x', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Streetlights').trigger('mousemove').click();
cy.get('#check-out-its-awesome-features').should('be.visible');
cy.get('#servers').should('be.visible');
});
it('hidden if not AsyncAPI 2.x.x', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.get('#check-out-its-awesome-features').should('not.exist');
cy.get('#servers').should('not.exist');
});
});
@@ -0,0 +1,52 @@
describe('Editor Preview Pane: OpenAPI 2.0, 3.0.x, 3.1.x', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('displays OpenAPI 2.0', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
// `.title` and `.version-stamp` are SwaggerUI specific css classes, that should only appear in the preview pane
cy.get('.title').contains('Swagger Petstore 2.0').should('be.visible');
cy.get('.version-stamp > .version').should('not.exist');
});
it('displays OpenAPI 3.0', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
// `.title` and `.version-stamp` are SwaggerUI specific css classes, that should only appear in the preview pane
cy.get('.title').contains('Swagger Petstore - OpenAPI 3.0').should('be.visible');
cy.get('.version-stamp > .version').should('be.visible').contains('OAS3').should('be.visible');
});
it('displays OpenAPI 3.1 fallback', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
// `.version-pragma__message` is a SwaggerEditor specific css class, that should only appear in the preview pane
cy.get('.version-pragma__message h3')
.contains('Unable to render editor content')
.should('be.visible');
cy.get('.version-pragma__message > div')
.contains('SwaggerUI does not currently support rendering of OpenAPI 3.1 definitions')
.should('be.visible');
});
it('should be hidden if not OpenAPI', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Petstore').trigger('mousemove').click();
// `.title` is a SwaggerUI specific css class
cy.get('.title').should('not.exist');
cy.get('Swagger Petstore').should('not.exist');
});
});
@@ -0,0 +1,33 @@
describe('read only', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
it('should toggle between allow-write and read-only', () => {
// default allow-write
cy.get(':nth-child(1) > .swagger-editor__editor-pane-bar-control > .octicon-unlock').should(
'be.visible'
);
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.should('not.have.attr', 'readonly');
// toggle to read-only
cy.get(':nth-child(1) > .swagger-editor__editor-pane-bar-control').click();
cy.get(':nth-child(1) > .swagger-editor__editor-pane-bar-control > .octicon-lock').should(
'be.visible'
);
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.should('have.attr', 'readonly');
// toggle back to allow-write
cy.get(':nth-child(1) > .swagger-editor__editor-pane-bar-control').click();
cy.get(':nth-child(1) > .swagger-editor__editor-pane-bar-control > .octicon-unlock').should(
'be.visible'
);
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.should('not.have.attr', 'readonly');
});
});
@@ -0,0 +1,370 @@
describe('Topbar', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
});
describe('File Dropdown Menu', () => {
it('should load file from URL', () => {
cy.contains('File').click(); // File Menu
cy.contains('Import URL')
.trigger('mousemove')
.click()
.get('#input-import-url')
.type(
'https://raw.githubusercontent.com/asyncapi/spec/v2.5.0/examples/streetlights-kafka.yml'
)
.get('.btn-primary')
.click();
cy.get('.view-lines > :nth-child(1)')
.should('not.have.text', '|') // applies to both OpenAPI and AsyncAPI cases if yaml improperly loaded
.should('contains.text', 'asyncapi');
});
it('should render "Import File" menu item', () => {
cy.contains('File').click(); // File Menu
cy.contains('Import File').should('exist');
});
it('should "Import File" and display rendered changes', () => {
/**
* Cypress does not handle native events like opening a File Dialog.
* The goal of this test is to see when the file is uploaded that the
* editor content and rendered UI changes.
* In this test, it is not required for Cypress to "interact" with the
* "File" Menu or the "Import File" menu item. If "interact" occurs
* with "Import File", test runner will output console warning:
* "File chooser dialog can only be shown with a user activation."
*/
cy.get('input[type=file]').attachFile('petstore-oas3.yaml', {
subjectType: 'input',
});
cy.wait(['@externalGeneratorServersOas3reqList', '@externalGeneratorClientsOas3reqList']);
// This assertion assumes change from non-OAS3 to OAS3, where a "badge" will exist for OAS3
cy.get('.version-stamp > .version').should('have.text', 'OAS3');
});
describe('Load Example nested menu', () => {
it('should load OpenAPI 3.1 Petstore example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(1)')
.should('contains.text', '3.1.0')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
it('should load OpenAPI 3.0 Petstore example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(1)')
.should('contains.text', '3.0.3')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
it('should load OpenAPI 2.0 Petstore example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(1)')
.should('contains.text', 'swagger')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
it('should load AsyncAPI 2.5 Petstore example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Petstore').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(3)')
.should('contains.text', 'Petstore')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
it('should load AsyncAPI 2.5 Streetlights example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Streetlights').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(3)')
.should('contains.text', 'Streetlights')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
it('should load API Design Systems example as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('API Design Systems').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(1)')
.should('contains.text', '2021-05-07')
.should('not.have.text', '{')
.should('not.have.text', '"');
});
});
describe('when content is JSON', () => {
/**
* vs. Edit Menu, operation also will initiate a file download without additional user input
* Final production version might not contain
* a fixture that we intend to load and display as JSON.
* So here we assume that we can load a fixture as YAML,
* then convert to JSON.
* Then assert expected File Menu item is displayed,
* However, no additional assertion for click event or download event
* unless we want to check for file existence and/or file contents
*/
it('should render clickable text: "Save (as JSON)', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to JSON').trigger('mousemove').click();
cy.contains('File').click();
cy.contains('Save (as JSON)').should('exist');
});
it('should render clickable text: "Convert and Save as YAML', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to JSON').trigger('mousemove').click();
cy.contains('File').click();
cy.contains('Convert and Save as YAML').should('exist');
});
});
describe('when content is YAML', () => {
/**
* vs. Edit Menu, operation also will initiate a file download without additional user input
* Here we assume that we can load a fixture as YAML.
* Then assert expected File Menu item is displayed,
* However, no additional assertion for click event or download event
* unless we want to check for file existence and/or file contents
*/
it('should render clickable text: "Save (as YAML)', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
cy.contains('File').click();
cy.contains('Save (as YAML)').should('exist');
});
it('should render clickable text: "Convert and Save as JSON', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('File').click();
cy.contains('Convert and Save as JSON').should('exist');
});
});
});
describe('Edit Dropdown Menu', () => {
it('should clear editor', () => {
cy.contains('Edit').click();
cy.contains('Clear').trigger('mousemove').click();
cy.get('.view-lines > :nth-child(1)').should('to.have.text', '');
});
describe('given editor content is in YAML format', () => {
it('displays "Convert To JSON" menu item', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to JSON').should('be.visible');
});
});
describe('given editor content is in JSON format', () => {
it('displays "Convert To YAML" menu item', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to JSON').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to YAML').should('be.visible');
});
});
describe('"Convert to OpenAPI 3.0.x" menu item', () => {
it('displays "Convert to OpenAPI 3.0.x" after loading OpenAPI 2.0 fixture', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to OpenAPI 3.0.x').should('be.visible');
});
it('should not display "Convert to OpenAPI 3.0.x" after loading OpenAPI 3.0 fixture', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.get('Convert to OpenAPI 3.0.x').should('not.exist');
});
it('should not display "Convert to OpenAPI 3.0.x" after loading AsyncAPI 2.5 fixture', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.get('Convert to OpenAPI 3.0.x').should('not.exist');
});
it('should call external http service to "Convert to OpenAPI 3.0.x" after loading OpenAPI 2.0 fixture', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.contains('Edit').click();
cy.contains('Convert to OpenAPI 3.0.x')
.should('be.visible')
.trigger('mousemove')
.click()
.wait('@externalConverterToOas3');
// This assertion assumes change from non-OAS3 to OAS3, where a "badge" will exist for OAS3
cy.get('.version-stamp > .version').should('have.text', 'OAS3');
});
});
});
describe('Generator Dropdown Menu(s)', () => {
/**
* By default, any "Generate Server" or "Generate Client" list
* is retrieved via an http service
* Clicking on a specific menu item from one of these lists
* will auto-download a generated file via an http service
* without further user action required
*/
beforeEach(() => {
cy.clearDownloadsFolder();
});
after(() => {
cy.clearDownloadsFolder();
});
const downloadsFolder = Cypress.config('downloadsFolder'); // use default setting
it('should render "Generate Server" and "Generate Client" dropdown menus when OpenAPI 2.0', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Server').should('be.visible');
cy.contains('Generate Client').should('be.visible');
});
it('should render "Generate Server" and "Generate Client" dropdown menus when OpenAPI 3.0', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Server').should('be.visible');
cy.contains('Generate Client').should('be.visible');
});
it('should NOT render "Generate Server" and "Generate Client" dropdown menus when OpenAPI 3.1', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.1 Petstore').trigger('mousemove').click();
cy.get('Generate Server').should('not.exist');
cy.get('Generate Client').should('not.exist');
});
it('should NOT render "Generate Server" and "Generate Client" dropdown menus when AsyncAPI 2.5', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('AsyncAPI 2.5 Petstore').trigger('mousemove').click();
cy.get('Generate Server').should('not.exist');
cy.get('Generate Client').should('not.exist');
});
it('should download a generated OpenAPI 3.0 Server file', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Server').should('be.visible').click();
cy.contains('blue') // mocked response value
.should('be.visible')
.trigger('mousemove')
.click()
.wait('@externalGeneratorOas3Download')
.readFile(`${downloadsFolder}/blue-server-generated.zip`)
.should('exist');
});
it('should download a generated OpenAPI 3.0 Client file', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 3.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Client').should('be.visible').click();
cy.contains('apple') // mocked response value
.should('be.visible')
.trigger('mousemove')
.click()
.wait('@externalGeneratorOas3Download')
.readFile(`${downloadsFolder}/apple-client-generated.zip`)
.should('exist');
});
it('should download a generated OpenAPI 2.0 Server file', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Server').should('be.visible').click();
cy.contains('blue') // mocked response value
.should('be.visible')
.trigger('mousemove')
.click()
.wait('@externalGeneratorServersOAS2reqDownloadUrl')
.wait('@externalGeneratorOas2Download')
.readFile(`${downloadsFolder}/blue-server-generated.zip`)
.should('exist');
});
it('should download a generated OpenAPI 2.0 Client file', () => {
cy.contains('File').click();
cy.contains('Load Example').trigger('mouseover');
cy.contains('OpenAPI 2.0 Petstore').trigger('mousemove').click();
cy.contains('Generate Client').should('be.visible').click();
cy.contains('apple') // mocked response value
.should('be.visible')
.trigger('mousemove')
.click()
.wait('@externalGeneratorClientsOAS2reqDownloadUrl')
.wait('@externalGeneratorOas2Download')
.readFile(`${downloadsFolder}/apple-client-generated.zip`)
.should('exist');
});
});
describe('About Drop Menu', () => {
it('should have expect menu items', () => {
cy.contains('About').click(); // About Menu
cy.contains('About Swagger Editor').should('exist');
cy.contains('View Docs').should('exist');
cy.contains('View on GitHub').should('exist');
});
});
});
@@ -0,0 +1,60 @@
describe('Monaco Editor with Validation Pane', () => {
beforeEach(() => {
cy.visitBlankPage();
cy.prepareAsyncAPI();
cy.prepareOasGenerator();
cy.waitForSplashScreen();
// move down to line 2, column 3
const moveToPosition = `{downArrow}{rightArrow}{rightArrow}`;
// introduce a typo error
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.click({ force: true })
.focused()
.type(`${moveToPosition}Q`);
cy.waitForContentPropagation();
});
/**
* note: future UX may make the table header <thead> always visible,
* or existing but collapsed
* expect table body <tbody> to always not exist if there are no errors
* make appropriate changes if/when needed
*/
it('should display visible Validation Pane table header and table body when error exists', () => {
cy.get('.swagger-editor__validation-table')
.should('exist')
.get('.swagger-editor__validation-table > thead')
.should('be.visible')
.get('.swagger-editor__validation-table > tbody')
.should('be.visible');
// some additional assertions just to make sure
cy.get('.swagger-editor__validation-table > thead > tr > :nth-child(1)')
.contains('line', { matchCase: false })
.should('be.visible');
cy.get('.swagger-editor__validation-table > thead > tr > :nth-child(2)')
.contains('description', { matchCase: false })
.should('be.visible');
// reflects line number from moveToPosition for validation error
cy.get('.swagger-editor__validation-table > tbody > :nth-child(1) > :nth-child(1) > div')
.contains('2')
.should('be.visible');
// validation error message is parser specific
cy.get('.swagger-editor__validation-table > tbody > :nth-child(1) > :nth-child(2) > div')
.contains('should NOT have')
.should('be.visible');
});
it('should not display Validation Pane after error is cleared', () => {
// fix the typo error
cy.get('.monaco-editor textarea:first', { timeout: 10000 })
.should('be.visible')
.click({ force: true })
.focused()
.type(`{backspace}`);
// re-assert
cy.get('.swagger-editor__validation-table > thead').should('not.exist');
cy.get('.swagger-editor__validation-table > tbody').should('not.exist');
});
});