Merge pull request #9546 from backstage/emmaindal/techdocs-cli-tests
[TechDocs CLI] adding cypress testing
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@techdocs/cli': patch
|
||||
---
|
||||
|
||||
- Adds `cypress` and `cypress-plugin-snapshots` as dependencies for integration and visual regression tests.
|
||||
- Updates README documentation with instructions for how to run tests.
|
||||
- Clarifies output text for prepack script.
|
||||
@@ -40,8 +40,25 @@ yarn start
|
||||
yarn techdocs-cli:dev [...options]
|
||||
```
|
||||
|
||||
### Using an example docs project
|
||||
|
||||
For the purpose of local development, we have created an example documentation project. You are of course also free to create your own local test site - all it takes is a `docs/index.md` and an `mkdocs.yml` in a directory.
|
||||
|
||||
```sh
|
||||
|
||||
cd packages/techdocs-cli/src/example-docs
|
||||
|
||||
# To get a view of your docs in Backstage, use:
|
||||
techdocs-cli serve
|
||||
|
||||
# To view the raw mkdocs site (without Backstage), use:
|
||||
techdocs-cli serve:mkdocs
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
#### E2E tests
|
||||
|
||||
Running unit tests requires mkdocs to be installed locally:
|
||||
|
||||
```sh
|
||||
@@ -51,18 +68,37 @@ pip install mkdocs-techdocs-core
|
||||
|
||||
Then run `yarn test`.
|
||||
|
||||
### Use an example docs project
|
||||
#### Cypress (Integration and Visual regression) tests
|
||||
|
||||
We have created an [example documentation project](https://github.com/backstage/techdocs-container/tree/main/mock-docs) and it's shipped with [techdocs-container](https://github.com/backstage/techdocs-container) repository, for the purpose of local development. But you are free to create your own local test site. All it takes is a `docs/index.md` and `mkdocs.yml` in a directory.
|
||||
Running cypress tests requires you to run the CLI locally against our example docs.
|
||||
|
||||
Run the local version of techdocs-cli against the example docs:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/backstage/techdocs-container.git
|
||||
# From the root of this repository run
|
||||
# NOTE: This will build the techdocs-cli-embedded-app and copy the output into the cli dist directory
|
||||
yarn build --scope @techdocs/cli
|
||||
|
||||
cd techdocs-container/mock-docs
|
||||
# Navigate to the example project
|
||||
cd packages/techdocs-cli/src/example-docs
|
||||
|
||||
# To get a view of your docs in Backstage, use:
|
||||
techdocs-cli serve
|
||||
|
||||
# To view the raw mkdocs site (without Backstage), use:
|
||||
techdocs-cli serve:mkdocs
|
||||
# Now execute the techdocs-cli serve command
|
||||
../../bin/techdocs-cli serve
|
||||
```
|
||||
|
||||
In another shell, run the cypress tests:
|
||||
|
||||
```sh
|
||||
# From the root of the project, navigate to the techdocs-cli package
|
||||
cd packages/techdocs-cli
|
||||
|
||||
# Run tests
|
||||
yarn test:cypress
|
||||
```
|
||||
|
||||
This will launch a cypress app where you can run the two different tests:
|
||||
|
||||
- `backstage_serve` - will run against the backstage server
|
||||
- `mkdocs_serve` - will run test against the mkdocs server
|
||||
|
||||
> If its the first time you run Cypress, it will run a "Verifying Cypress can run" step. This step can result in a "Cypress verification timed out" error. If that is the case, let the verification step run and then run the command again and it should succeed.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"env": {
|
||||
"mkDocsBaseUrl": "http://localhost:8000",
|
||||
"backstageBaseUrl": "http://localhost:3000",
|
||||
"cypress-plugin-snapshots": {
|
||||
"autoCleanUp": false,
|
||||
"imageConfig": {
|
||||
"resizeDevicePixelRatio": true,
|
||||
"threshold": 0.01
|
||||
}
|
||||
}
|
||||
},
|
||||
"viewportWidth": 1920,
|
||||
"viewportHeight": 1080,
|
||||
"includeShadowDom": true,
|
||||
"ignoreTestFiles": ["**/__snapshots__/*", "**/__image_snapshots__/*"]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"plugins": ["cypress"],
|
||||
"extends": ["plugin:cypress/recommended"],
|
||||
"rules": {
|
||||
"jest/expect-expect": [
|
||||
"error",
|
||||
{
|
||||
"assertFunctionNames": ["expect", "cy.contains", "cy.document"]
|
||||
}
|
||||
],
|
||||
"import/no-extraneous-dependencies": [
|
||||
"error",
|
||||
{
|
||||
"devDependencies": true,
|
||||
"optionalDependencies": true,
|
||||
"peerDependencies": true,
|
||||
"bundledDependencies": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 167 KiB |
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
/// <reference types="cypress" />
|
||||
describe('TechDocs Live Preview - Backstage Serve', () => {
|
||||
it('successfully serves documentation', () => {
|
||||
cy.visit(`${Cypress.env('backstageBaseUrl')}/docs/default/component/local`);
|
||||
cy.contains('hello mock docs');
|
||||
});
|
||||
|
||||
it('successfully navigates to sub page of documentation', () => {
|
||||
cy.contains('SubDocs').click();
|
||||
cy.contains('Home 2').click();
|
||||
cy.contains(
|
||||
'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
|
||||
);
|
||||
});
|
||||
|
||||
it('successfully renders all Backstage main elements', () => {
|
||||
cy.contains('header', 'Live preview environment');
|
||||
cy.get('[data-testid="sidebar-root"]')
|
||||
.children()
|
||||
.should('have.length.gt', 0);
|
||||
});
|
||||
|
||||
it('successfully renders all extracted MkDocs main elements', () => {
|
||||
// as it gets replaced by Backstage header
|
||||
cy.get('.md-header').should('have.length', 0);
|
||||
cy.get('.md-main').should('have.length', 1);
|
||||
cy.contains(
|
||||
'.md-main',
|
||||
'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
|
||||
);
|
||||
cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
|
||||
cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
|
||||
cy.get('.md-footer').should('have.length', 1);
|
||||
});
|
||||
|
||||
it('toMatchImageSnapshot - Backstage TechDocs Page', () => {
|
||||
cy.visit(
|
||||
`${Cypress.env('backstageBaseUrl')}/docs/default/component/local`,
|
||||
).then(() => {
|
||||
cy.document().toMatchImageSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
/// <reference types="cypress" />
|
||||
describe('TechDocs Live Preview - MkDocs Serve', () => {
|
||||
it('successfully serves documentation', () => {
|
||||
cy.visit(Cypress.env('mkDocsBaseUrl'));
|
||||
cy.contains('hello mock docs');
|
||||
});
|
||||
|
||||
it('successfully navigates to sub page of documentation', () => {
|
||||
cy.contains('SubDocs').click();
|
||||
cy.contains('Home 2').click();
|
||||
cy.contains(
|
||||
'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
|
||||
);
|
||||
});
|
||||
|
||||
it('successfully renders all main elements', () => {
|
||||
cy.get('.md-header').should('have.length', 1);
|
||||
cy.get('.md-main').should('have.length', 1);
|
||||
cy.contains(
|
||||
'.md-main',
|
||||
'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
|
||||
);
|
||||
cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
|
||||
cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
|
||||
cy.get('.md-footer').should('have.length', 1);
|
||||
});
|
||||
|
||||
it('toMatchImageSnapshot - MkDocs Page', () => {
|
||||
cy.visit(Cypress.env('mkDocsBaseUrl')).then(() => {
|
||||
cy.document().toMatchImageSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
// ***********************************************************
|
||||
// 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)
|
||||
|
||||
const { initPlugin } = require('cypress-plugin-snapshots/plugin');
|
||||
|
||||
/**
|
||||
* @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
|
||||
initPlugin(on, config);
|
||||
return config;
|
||||
};
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 392 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 322 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 322 KiB |
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
// 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) => { ... })
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
// 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';
|
||||
import 'cypress-plugin-snapshots/commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
@@ -30,6 +30,7 @@
|
||||
"test": "backstage-cli package test --testPathIgnorePatterns=src/e2e.test.ts",
|
||||
"test:e2e": "backstage-cli test src/e2e.test.ts",
|
||||
"test:e2e:ci": "backstage-cli test --watchAll=false --ci src/e2e.test.ts",
|
||||
"test:cypress": "cypress open",
|
||||
"prepack": "./scripts/prepack.sh"
|
||||
},
|
||||
"bin": {
|
||||
@@ -44,9 +45,11 @@
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/serve-handler": "^6.1.0",
|
||||
"@types/webpack-env": "^1.15.3",
|
||||
"techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app",
|
||||
"cypress": "^7.3.0",
|
||||
"cypress-plugin-snapshots": "^1.4.4",
|
||||
"find-process": "^1.4.5",
|
||||
"nodemon": "^2.0.2",
|
||||
"techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app",
|
||||
"ts-node": "^10.0.0"
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -23,4 +23,4 @@ TECHDOCS_CLI_EMBEDDED_APP_DIR="$TECHDOCS_CLI_DIR"/../techdocs-cli-embedded-app
|
||||
echo "🚚 Copying embedded app into dist/embedded-app"
|
||||
rm -rf "$TECHDOCS_CLI_DIR"/dist/embedded-app
|
||||
cp -r "$TECHDOCS_CLI_EMBEDDED_APP_DIR"/dist "$TECHDOCS_CLI_DIR"/dist/embedded-app
|
||||
echo "🏁 Ready!"
|
||||
echo "🏁 Finished copying embedded app into dist/embedded-app!"
|
||||
|
||||
@@ -58,7 +58,7 @@ const timeout = 25000;
|
||||
jest.setTimeout(timeout * 2);
|
||||
|
||||
describe('end-to-end', () => {
|
||||
const cwd = path.resolve(__dirname, 'fixture');
|
||||
const cwd = path.resolve(__dirname, 'example-docs');
|
||||
|
||||
afterEach(async () => {
|
||||
// On Windows the pid of a spawned process may be wrong
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
site/
|
||||
@@ -0,0 +1,92 @@
|
||||
## hello mock docs
|
||||
|
||||
!!! test
|
||||
Testing something
|
||||
|
||||
Abbreviations:
|
||||
Some text about MOCDOC
|
||||
|
||||
This is a paragraph.
|
||||
{: #test_id .test_class }
|
||||
|
||||
Apple
|
||||
: A fruit.
|
||||
|
||||
```javascript
|
||||
import { test } from 'something';
|
||||
|
||||
const addThingToThing = (a, b) a + b;
|
||||
```
|
||||
|
||||
- [abc](#abc)
|
||||
- [xyz](#xyz)
|
||||
|
||||
## abc
|
||||
|
||||
This is a b c.
|
||||
|
||||
## xyz
|
||||
|
||||
This is x y z.
|
||||
|
||||
# Emojis
|
||||
|
||||
:bulb: :smile:
|
||||
|
||||
# Code blocks
|
||||
|
||||
```javascript
|
||||
import { test } from 'something';
|
||||
|
||||
const addThingToThing = (a, b) a + b;
|
||||
```
|
||||
|
||||
# Grouped Code blocks
|
||||
|
||||
=== "JavaScript"
|
||||
|
||||
```javascript
|
||||
import { test } from 'something';
|
||||
|
||||
const addThingToThing = (a, b) a + b;
|
||||
```
|
||||
|
||||
=== "Java"
|
||||
|
||||
```java
|
||||
public void function() {
|
||||
test();
|
||||
}
|
||||
```
|
||||
|
||||
```java tab="java"
|
||||
public void function() {
|
||||
test();
|
||||
}
|
||||
```
|
||||
|
||||
```java tab="java 2"
|
||||
public void function() {
|
||||
test();
|
||||
}
|
||||
```
|
||||
|
||||
# MDX truly sane lists
|
||||
|
||||
- attributes
|
||||
|
||||
- customer
|
||||
- first_name
|
||||
- test
|
||||
- family_name
|
||||
- email
|
||||
- person
|
||||
- first_name
|
||||
- family_name
|
||||
- birth_date
|
||||
- subscription_id
|
||||
|
||||
- request
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
*[MOCDOC]: Mock Documentation
|
||||
+3
-1
@@ -2,7 +2,9 @@ site_name: docs-test-fixture
|
||||
site_description: Documentation site test fixture
|
||||
|
||||
nav:
|
||||
- HOME: README.md
|
||||
- Home: index.md
|
||||
- SubDocs: '!include ./sub-docs/mkdocs.yml'
|
||||
- Plugins: '*include ./plugins/*/mkdocs.yml'
|
||||
|
||||
plugins:
|
||||
- techdocs-core
|
||||
@@ -0,0 +1,4 @@
|
||||
# Plugin A
|
||||
|
||||
This is a description of Plugin A. This file exists to prove that glob'd
|
||||
includes using the `*include` syntax work as expected.
|
||||
@@ -0,0 +1,5 @@
|
||||
site_name: Plugin A
|
||||
site_description: A description of Plugin A
|
||||
|
||||
nav:
|
||||
- Introduction: index.md
|
||||
@@ -0,0 +1,4 @@
|
||||
# Plugin B
|
||||
|
||||
This is a description of Plugin B. This file exists to prove that glob'd
|
||||
includes using the `*include` syntax work as expected.
|
||||
@@ -0,0 +1,5 @@
|
||||
site_name: Plugin B
|
||||
site_description: A description of Plugin B
|
||||
|
||||
nav:
|
||||
- Introduction: index.md
|
||||
@@ -0,0 +1 @@
|
||||
### This is an md file in another docs folder using the [MkDocs Monorepo Plugin](https://github.com/spotify/mkdocs-monorepo-plugin)
|
||||
@@ -0,0 +1,4 @@
|
||||
site_name: subdocs
|
||||
|
||||
nav:
|
||||
- Home 2: 'index.md'
|
||||
@@ -1 +0,0 @@
|
||||
# Test Fixture
|
||||
Reference in New Issue
Block a user