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
|
||||
run: |
|
||||
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": {
|
||||
"docusaurus": "docusaurus",
|
||||
"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:withoutAuth": "OAUTH_ENABLE=false docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
@ -13,7 +13,9 @@
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"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": {
|
||||
"@docusaurus/core": "2.0.0-beta.2",
|
||||
@ -42,5 +44,11 @@
|
||||
"last 1 firefox 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() {
|
||||
return (
|
||||
<div className={style.container}>
|
||||
<div data-cy="cy-signin" className={style.container}>
|
||||
<h1 className={style.h1}>Welcome on Dagger documentation</h1>
|
||||
<p>Please Sign In to Github to get access to the doc</p>
|
||||
<div data-cy="cy-btn-signin">
|
||||
<GithubLoginButton className={style.btn__github} onClick={() => window.location.href = process.env.REACT_APP_GITHUB_AUTHORIZE_URI} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -11,7 +11,7 @@ export default function DocPageRedirect() {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={`container ${style.wrapper}`}>
|
||||
<div data-cy="cy-page-redirect" className={`container ${style.wrapper}`}>
|
||||
<div className={`row ${style.row}`}>
|
||||
<div className="col col--4 col--offset-2">
|
||||
<h1 className={style.h1}>Oups!</h1>
|
||||
|
@ -13,15 +13,15 @@ import DocSidebar from '@theme/DocSidebar';
|
||||
import MDXComponents from '@theme/MDXComponents';
|
||||
import NotFound from '@theme/NotFound';
|
||||
import IconArrow from '@theme/IconArrow';
|
||||
import { matchPath } from '@docusaurus/router';
|
||||
import { translate } from '@docusaurus/Translate';
|
||||
import {matchPath} from '@docusaurus/router';
|
||||
import {translate} from '@docusaurus/Translate';
|
||||
import clsx from 'clsx';
|
||||
import styles from './styles.module.css';
|
||||
import { ThemeClassNames, docVersionSearchTag } from '@docusaurus/theme-common';
|
||||
import DocPageCustom from '../../components/DocPageCustom'
|
||||
import {ThemeClassNames, docVersionSearchTag} from '@docusaurus/theme-common';
|
||||
import DocPageCustom from '../../components/DocPageCustom';
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
|
||||
function getSidebar({ versionMetadata, currentDocRoute }) {
|
||||
function getSidebar({versionMetadata, currentDocRoute}) {
|
||||
function addTrailingSlash(str) {
|
||||
return str.endsWith('/') ? str : `${str}/`;
|
||||
}
|
||||
@ -30,7 +30,7 @@ function getSidebar({ versionMetadata, currentDocRoute }) {
|
||||
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
|
||||
// trailingSlash is handled globally at the framework level, not plugin level
|
||||
|
||||
@ -45,10 +45,10 @@ function getSidebar({ versionMetadata, currentDocRoute }) {
|
||||
};
|
||||
}
|
||||
|
||||
function DocPageContent({ currentDocRoute, versionMetadata, children }) {
|
||||
const { siteConfig, isClient } = useDocusaurusContext();
|
||||
const { pluginId, version } = versionMetadata;
|
||||
const { sidebarName, sidebar } = getSidebar({
|
||||
function DocPageContent({currentDocRoute, versionMetadata, children}) {
|
||||
const {siteConfig, isClient} = useDocusaurusContext();
|
||||
const {pluginId, version} = versionMetadata;
|
||||
const {sidebarName, sidebar} = getSidebar({
|
||||
versionMetadata,
|
||||
currentDocRoute,
|
||||
});
|
||||
@ -149,7 +149,7 @@ function DocPageContent({ currentDocRoute, versionMetadata, children }) {
|
||||
|
||||
function DocPage(props) {
|
||||
const {
|
||||
route: { routes: docRoutes },
|
||||
route: {routes: docRoutes},
|
||||
versionMetadata,
|
||||
location,
|
||||
} = props;
|
||||
@ -159,9 +159,12 @@ function DocPage(props) {
|
||||
const userAgent = ExecutionEnvironment.canUseDOM ? navigator.userAgent : null;
|
||||
|
||||
// DocPage Swizzle
|
||||
const [userAccessStatus, setUserAccessStatus] = useState((() => {
|
||||
if (typeof window !== "undefined") return JSON.parse(window.localStorage.getItem('user'))
|
||||
})())
|
||||
const [userAccessStatus, setUserAccessStatus] = useState(
|
||||
(() => {
|
||||
if (typeof window !== 'undefined')
|
||||
return JSON.parse(window.localStorage.getItem('user'));
|
||||
})(),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
import('amplitude-js').then(amplitude => {
|
||||
@ -191,9 +194,11 @@ function DocPage(props) {
|
||||
<DocPageContent
|
||||
currentDocRoute={currentDocRoute}
|
||||
versionMetadata={versionMetadata}>
|
||||
<div data-cy="cy-doc-content">
|
||||
{renderRoutes(docRoutes, {
|
||||
versionMetadata,
|
||||
})}
|
||||
</div>
|
||||
</DocPageContent>
|
||||
);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user