docs: ✅ init cypress test e2e
Signed-off-by: jffarge <jf@dagger.io>
This commit is contained in:
parent
795430024b
commit
868339e174
31
.github/workflows/ci.yml
vendored
31
.github/workflows/ci.yml
vendored
@ -120,3 +120,34 @@ jobs:
|
|||||||
- name: Universe Test
|
- name: Universe Test
|
||||||
run: |
|
run: |
|
||||||
make universe-test
|
make universe-test
|
||||||
|
|
||||||
|
cypress-run:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Cypress run
|
||||||
|
uses: cypress-io/github-action@v2
|
||||||
|
env:
|
||||||
|
REACT_APP_CLIENT_ID: 123
|
||||||
|
REACT_APP_CLIENT_SECRET: 123
|
||||||
|
REACT_APP_DAGGER_SITE_URI: https://dagger.io
|
||||||
|
REACT_APP_API_PROXY_ENABLE: false
|
||||||
|
REACT_APP_AMPLITUDE_ID: 123
|
||||||
|
with:
|
||||||
|
config: chromeWebSecurity=false
|
||||||
|
start: |
|
||||||
|
yarn start
|
||||||
|
yarn start:withAuth
|
||||||
|
working-directory: ./website
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: cypress-screenshots
|
||||||
|
path: website/cypress/screenshots
|
||||||
|
# Test run video was always captured, so this action uses "always()" condition
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: cypress-videos
|
||||||
|
path: website/cypress/videos
|
||||||
|
9
website/.prettierrc
Normal file
9
website/.prettierrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"arrowParens": "always",
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"jsxBracketSameLine": true,
|
||||||
|
"printWidth": 80,
|
||||||
|
"proseWrap": "never",
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
4
website/cypress.json
Normal file
4
website/cypress.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"chromeWebSecurity": false,
|
||||||
|
"video": false
|
||||||
|
}
|
4
website/cypress/fixtures/bad_credential.json
Normal file
4
website/cypress/fixtures/bad_credential.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"message": "Bad credentials",
|
||||||
|
"documentation_url": "https://docs.github.com/rest"
|
||||||
|
}
|
5
website/cypress/fixtures/bad_verification.code.json
Normal file
5
website/cypress/fixtures/bad_verification.code.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"error":"bad_verification_code",
|
||||||
|
"error_description":"The code passed is incorrect or expired.",
|
||||||
|
"error_uri":"https://docs.github.com/apps/managing-oauth-apps/troubleshooting-oauth-app-access-token-request-errors/#bad-verification-code"
|
||||||
|
}
|
53
website/cypress/integration/docs.spec.js
Normal file
53
website/cypress/integration/docs.spec.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
describe('Visit Docs website', function() {
|
||||||
|
|
||||||
|
it('Visit docs website without authentication', function() {
|
||||||
|
cy.visit('http://localhost:3000')
|
||||||
|
cy.get('[data-cy="cy-signin"]').should('not.exist')
|
||||||
|
}),
|
||||||
|
|
||||||
|
it('Visit docs website with authentication', function() {
|
||||||
|
cy.visit('http://localhost:3001')
|
||||||
|
cy.get('[data-cy="cy-signin"]').should('exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
context('When user is authenticated', function() {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.setLocalStorage('user', "{\"permission\":true,\"login\":\"slumbering\"}")
|
||||||
|
cy.intercept('/t', 'success').as('logAmplitude')
|
||||||
|
cy.visit(('http://localhost:3001'))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Visit docs website with a valid authenticated user', function() {
|
||||||
|
cy.get('[data-cy=cy-doc-content]').should('exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('log to amplitude when user visit another page', function() {
|
||||||
|
cy.get('[data-cy=cy-doc-content]').should('exist')
|
||||||
|
cy.get('.menu > :nth-child(2) > :nth-child(2) > .menu__link').click()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
context('When user is not authorized', function() {
|
||||||
|
it('Redirect user after unsuccessful sign in', function() {
|
||||||
|
cy.intercept('**/login/oauth/access_token?code=jergub54545&client_id=123&client_secret=321', {fixture: 'bad_verification.code.json'})
|
||||||
|
cy.intercept('**/user', (req) => {
|
||||||
|
req.continue((res) => {
|
||||||
|
expect(res.statusCode).to.be.equal(401)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
cy.visit('http://localhost:3001?code=jergub54545')
|
||||||
|
cy.get('[data-cy=cy-page-redirect]').should('exist')
|
||||||
|
// cy.wait(10000)
|
||||||
|
// cy.location().should((location) => {
|
||||||
|
// expect(location.host).to.eq('dagger.io')
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Visit docs website with a user not authorized', function() {
|
||||||
|
cy.setLocalStorage('user', "{\"permission\":false,\"login\":\"slumbering\"}")
|
||||||
|
cy.visit('http://localhost:3001')
|
||||||
|
cy.get('[data-cy=cy-page-redirect]').should('exist')
|
||||||
|
cy.intercept('/t', 'success')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
22
website/cypress/plugins/index.js
Normal file
22
website/cypress/plugins/index.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************************
|
||||||
|
// 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
|
||||||
|
}
|
26
website/cypress/support/commands.js
Normal file
26
website/cypress/support/commands.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// ***********************************************
|
||||||
|
// 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) => { ... })
|
||||||
|
import "cypress-localstorage-commands"
|
20
website/cypress/support/index.js
Normal file
20
website/cypress/support/index.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// ***********************************************************
|
||||||
|
// 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'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
4
website/cypress/videos/.gitignore
vendored
Normal file
4
website/cypress/videos/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"docusaurus": "docusaurus",
|
"docusaurus": "docusaurus",
|
||||||
"start": "OAUTH_ENABLE=false docusaurus start",
|
"start": "OAUTH_ENABLE=false docusaurus start",
|
||||||
"start:withAuth": "OAUTH_ENABLE=true docusaurus start",
|
"start:withAuth": "OAUTH_ENABLE=true docusaurus start --port=3001",
|
||||||
"build": "OAUTH_ENABLE=true docusaurus build",
|
"build": "OAUTH_ENABLE=true docusaurus build",
|
||||||
"build:withoutAuth": "OAUTH_ENABLE=false docusaurus build",
|
"build:withoutAuth": "OAUTH_ENABLE=false docusaurus build",
|
||||||
"swizzle": "docusaurus swizzle",
|
"swizzle": "docusaurus swizzle",
|
||||||
@ -13,7 +13,9 @@
|
|||||||
"clear": "docusaurus clear",
|
"clear": "docusaurus clear",
|
||||||
"serve": "docusaurus serve",
|
"serve": "docusaurus serve",
|
||||||
"write-translations": "docusaurus write-translations",
|
"write-translations": "docusaurus write-translations",
|
||||||
"write-heading-ids": "docusaurus write-heading-ids"
|
"write-heading-ids": "docusaurus write-heading-ids",
|
||||||
|
"start-server": "concurrently \"OAUTH_ENABLE=false yarn docusaurus start --port=3000 --no-open\" \"OAUTH_ENABLE=true yarn docusaurus start --port=3001 --no-open\"",
|
||||||
|
"ci": "start-server-and-test 'yarn start-server' '3000|3001' 'yarn run cypress run'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "2.0.0-beta.2",
|
"@docusaurus/core": "2.0.0-beta.2",
|
||||||
@ -42,5 +44,11 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"concurrently": "^6.2.0",
|
||||||
|
"cypress": "^7.6.0",
|
||||||
|
"cypress-localstorage-commands": "^1.4.5",
|
||||||
|
"start-server-and-test": "^1.12.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,12 @@ import style from './DocPageAuthentication.module.css'
|
|||||||
|
|
||||||
export default function DocAuthentication() {
|
export default function DocAuthentication() {
|
||||||
return (
|
return (
|
||||||
<div className={style.container}>
|
<div data-cy="cy-signin" className={style.container}>
|
||||||
<h1 className={style.h1}>Welcome on Dagger documentation</h1>
|
<h1 className={style.h1}>Welcome on Dagger documentation</h1>
|
||||||
<p>Please Sign In to Github to get access to the doc</p>
|
<p>Please Sign In to Github to get access to the doc</p>
|
||||||
<GithubLoginButton className={style.btn__github} onClick={() => window.location.href = process.env.REACT_APP_GITHUB_AUTHORIZE_URI} />
|
<div data-cy="cy-btn-signin">
|
||||||
|
<GithubLoginButton className={style.btn__github} onClick={() => window.location.href = process.env.REACT_APP_GITHUB_AUTHORIZE_URI} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ export default function DocPageRedirect() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`container ${style.wrapper}`}>
|
<div data-cy="cy-page-redirect" className={`container ${style.wrapper}`}>
|
||||||
<div className={`row ${style.row}`}>
|
<div className={`row ${style.row}`}>
|
||||||
<div className="col col--4 col--offset-2">
|
<div className="col col--4 col--offset-2">
|
||||||
<h1 className={style.h1}>Oups!</h1>
|
<h1 className={style.h1}>Oups!</h1>
|
||||||
|
@ -13,15 +13,15 @@ import DocSidebar from '@theme/DocSidebar';
|
|||||||
import MDXComponents from '@theme/MDXComponents';
|
import MDXComponents from '@theme/MDXComponents';
|
||||||
import NotFound from '@theme/NotFound';
|
import NotFound from '@theme/NotFound';
|
||||||
import IconArrow from '@theme/IconArrow';
|
import IconArrow from '@theme/IconArrow';
|
||||||
import { matchPath } from '@docusaurus/router';
|
import {matchPath} from '@docusaurus/router';
|
||||||
import { translate } from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import { ThemeClassNames, docVersionSearchTag } from '@docusaurus/theme-common';
|
import {ThemeClassNames, docVersionSearchTag} from '@docusaurus/theme-common';
|
||||||
import DocPageCustom from '../../components/DocPageCustom'
|
import DocPageCustom from '../../components/DocPageCustom';
|
||||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||||
|
|
||||||
function getSidebar({ versionMetadata, currentDocRoute }) {
|
function getSidebar({versionMetadata, currentDocRoute}) {
|
||||||
function addTrailingSlash(str) {
|
function addTrailingSlash(str) {
|
||||||
return str.endsWith('/') ? str : `${str}/`;
|
return str.endsWith('/') ? str : `${str}/`;
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ function getSidebar({ versionMetadata, currentDocRoute }) {
|
|||||||
return str.endsWith('/') ? str.slice(0, -1) : str;
|
return str.endsWith('/') ? str.slice(0, -1) : str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permalinkToSidebar, docsSidebars } = versionMetadata; // With/without trailingSlash, we should always be able to get the appropriate sidebar
|
const {permalinkToSidebar, docsSidebars} = versionMetadata; // With/without trailingSlash, we should always be able to get the appropriate sidebar
|
||||||
// note: docs plugin permalinks currently never have trailing slashes
|
// note: docs plugin permalinks currently never have trailing slashes
|
||||||
// trailingSlash is handled globally at the framework level, not plugin level
|
// trailingSlash is handled globally at the framework level, not plugin level
|
||||||
|
|
||||||
@ -45,10 +45,10 @@ function getSidebar({ versionMetadata, currentDocRoute }) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function DocPageContent({ currentDocRoute, versionMetadata, children }) {
|
function DocPageContent({currentDocRoute, versionMetadata, children}) {
|
||||||
const { siteConfig, isClient } = useDocusaurusContext();
|
const {siteConfig, isClient} = useDocusaurusContext();
|
||||||
const { pluginId, version } = versionMetadata;
|
const {pluginId, version} = versionMetadata;
|
||||||
const { sidebarName, sidebar } = getSidebar({
|
const {sidebarName, sidebar} = getSidebar({
|
||||||
versionMetadata,
|
versionMetadata,
|
||||||
currentDocRoute,
|
currentDocRoute,
|
||||||
});
|
});
|
||||||
@ -149,7 +149,7 @@ function DocPageContent({ currentDocRoute, versionMetadata, children }) {
|
|||||||
|
|
||||||
function DocPage(props) {
|
function DocPage(props) {
|
||||||
const {
|
const {
|
||||||
route: { routes: docRoutes },
|
route: {routes: docRoutes},
|
||||||
versionMetadata,
|
versionMetadata,
|
||||||
location,
|
location,
|
||||||
} = props;
|
} = props;
|
||||||
@ -159,9 +159,12 @@ function DocPage(props) {
|
|||||||
const userAgent = ExecutionEnvironment.canUseDOM ? navigator.userAgent : null;
|
const userAgent = ExecutionEnvironment.canUseDOM ? navigator.userAgent : null;
|
||||||
|
|
||||||
// DocPage Swizzle
|
// DocPage Swizzle
|
||||||
const [userAccessStatus, setUserAccessStatus] = useState((() => {
|
const [userAccessStatus, setUserAccessStatus] = useState(
|
||||||
if (typeof window !== "undefined") return JSON.parse(window.localStorage.getItem('user'))
|
(() => {
|
||||||
})())
|
if (typeof window !== 'undefined')
|
||||||
|
return JSON.parse(window.localStorage.getItem('user'));
|
||||||
|
})(),
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
import('amplitude-js').then(amplitude => {
|
import('amplitude-js').then(amplitude => {
|
||||||
@ -191,9 +194,11 @@ function DocPage(props) {
|
|||||||
<DocPageContent
|
<DocPageContent
|
||||||
currentDocRoute={currentDocRoute}
|
currentDocRoute={currentDocRoute}
|
||||||
versionMetadata={versionMetadata}>
|
versionMetadata={versionMetadata}>
|
||||||
{renderRoutes(docRoutes, {
|
<div data-cy="cy-doc-content">
|
||||||
versionMetadata,
|
{renderRoutes(docRoutes, {
|
||||||
})}
|
versionMetadata,
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</DocPageContent>
|
</DocPageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user