├── .dockerignore ├── .env ├── .eslintrc ├── .gitignore ├── .prettierrc.json ├── .vscode └── settings.json ├── Dockerfile ├── LICENSE ├── Notes On Spearmintv15.md ├── README-dev.md ├── README.md ├── WriteUpForStateObjectImprovement.js ├── babel.config.js ├── declaration.d.ts ├── jest.config.js ├── package-lock.json ├── package.json ├── public ├── LoadProjectDemo.gif ├── LoginDemo.gif ├── RunDemo.gif ├── SaveDemo.gif ├── ShowDemo.gif ├── SpearmintGenerateTest.webp ├── SpearmintRunTest.webp ├── VcXsrv.png ├── demo.png ├── docker.png ├── electron.jsx ├── icon.icns ├── icon.png ├── index.html ├── manifest.json ├── moon.png ├── openFolder.webp ├── saveTest.webp ├── spearmint.svg ├── spearmint_crop.png ├── sun.png ├── testingModal.png └── x410.png ├── server ├── config │ └── passport.js ├── controllers │ ├── cookieController.js │ ├── sessionController.js │ ├── testStateController.js │ └── userController.js ├── models │ ├── sessionModel.js │ ├── testStateModel.js │ └── userModel.js ├── routes │ └── router.js ├── server.js └── utils │ └── backendTypes.ts ├── src ├── App.jsx ├── App.module.scss ├── __tests__ │ ├── Action.test.jsx │ ├── Assertion.test.jsx │ ├── EditorView.test.js │ ├── Hooks.test.js │ ├── ModeSwitch.test.js │ ├── NavBar.test.js │ ├── ProjectLoaderTests │ │ └── projectLoader.test.js │ ├── TestCard.test.jsx │ ├── TestFile.test.jsx │ ├── TestMenuButtons.test.js │ ├── accReducer.test.js │ ├── endpointReducer.test.js │ ├── globalReducer.test.js │ ├── graphQLReducer.test.js │ ├── puppeteerReducer.test.ts │ ├── reactReducer.test.js │ ├── reactTestCase.test.js │ ├── reduxActionCreator.test.js │ ├── reduxMiddleware.test.js │ ├── reduxReducerComponent.test.js │ ├── reduxTestCase.test.js │ ├── reduxTestCaseReducer.test.ts │ ├── reduxThunk.test.js │ ├── solidReducer.test.js │ ├── spec.e2e.js │ ├── spec.integra.js │ ├── spec.test.js │ ├── styleMock.js │ ├── svelteReducer.test.js │ ├── vueReducer.test.js │ └── wdio.conf.js ├── assets │ ├── icons │ │ └── add-black-18dp.svg │ ├── images │ │ ├── close.png │ │ ├── content-save-outline.png │ │ ├── describe.png │ │ ├── describe2.png │ │ ├── describehelp.png │ │ ├── drag-vertical.png │ │ ├── file-document-outline.svg │ │ ├── file-export.png │ │ ├── folder-open.png │ │ ├── folder-outline.svg │ │ ├── folder_open.png │ │ ├── google-chrome.png │ │ ├── help-circle.png │ │ ├── home.png │ │ ├── leaf.png │ │ ├── menu.png │ │ ├── minus-box-outline.png │ │ ├── newReact.png │ │ ├── plus-box.png │ │ ├── plus.png │ │ ├── spearmintHomepage.png │ │ ├── testfile.png │ │ └── visual-studio-code.png │ └── stylesheets │ │ ├── colors.scss │ │ ├── fonts.scss │ │ ├── global.scss │ │ └── reset.scss ├── components │ ├── AccTestComponent │ │ ├── AccTestTypes │ │ │ ├── AccTestTypes.module.scss │ │ │ └── AccTestTypes.tsx │ │ ├── CatTagFilter │ │ │ ├── CatTagFilter.module.scss │ │ │ └── CatTagFilter.tsx │ │ ├── DescribeRenderer │ │ │ ├── DescribeRenderer.module.scss │ │ │ └── DescribeRenderer.tsx │ │ ├── ItRenderer │ │ │ ├── ItRenderer.module.scss │ │ │ └── ItRenderer.tsx │ │ ├── PuppeteerUrl │ │ │ └── PuppeteerUrl.tsx │ │ └── StandardTagFilter │ │ │ ├── StandardTagFilter.module.scss │ │ │ └── StandardTagFilter.tsx │ ├── AutoComplete │ │ ├── AutoComplete.module.scss │ │ ├── AutoComplete.tsx │ │ ├── AutoCompleteMockData.module.scss │ │ ├── AutoCompleteMockData.tsx │ │ ├── UpdatedAutoComplete.tsx │ │ └── UpdatedAutoCompleteMockData.tsx │ ├── BrowserView │ │ ├── BrowserView.module.scss │ │ └── BrowserView.tsx │ ├── CypressTestCase.tsx │ ├── EditorView │ │ ├── EditorView.module.scss │ │ └── EditorView.tsx │ ├── EndpointTestComponent │ │ ├── Endpoint.module.scss │ │ ├── Endpoint.tsx │ │ ├── EndpointAssertion.tsx │ │ └── JestMatchers.ts │ ├── FileDirectory │ │ ├── FileDirectory.module.scss │ │ └── FileDirectory.tsx │ ├── GraphQLTestComponent │ │ ├── GraphQL.module.scss │ │ ├── GraphQL.tsx │ │ ├── GraphQLAssertion.tsx │ │ └── JestMatchers.ts │ ├── InputTextField.jsx │ ├── Modals │ │ ├── ExportFileModal.tsx │ │ ├── Modal.module.scss │ │ ├── Modal.tsx │ │ ├── UploadTestModal.tsx │ │ └── modalHooks.ts │ ├── ModeSwitch │ │ ├── ModeSwitch.module.scss │ │ └── ModeSwitch.tsx │ ├── NavBar │ │ ├── NavBar.module.scss │ │ └── NavBar.tsx │ ├── OpenFolder │ │ ├── OpenFolderButton.module.scss │ │ └── OpenFolderButton.tsx │ ├── PuppeteerTestComponent │ │ ├── PaintTiming │ │ │ ├── PaintTiming.module.scss │ │ │ └── PaintTiming.tsx │ │ └── PuppeteerBrowerSetting │ │ │ └── PuppeteerBrowserSetting.tsx │ ├── ReactHooksTestComponent │ │ ├── HookUpdates │ │ │ ├── HookUpdates.module.scss │ │ │ └── HookUpdates.tsx │ │ ├── HooksAssertion.tsx │ │ └── HooksCallback.tsx │ ├── ReactTestComponent │ │ ├── Action │ │ │ ├── Action.module.scss │ │ │ ├── Action.tsx │ │ │ ├── CypressAction.module.scss │ │ │ ├── commandStep.tsx │ │ │ └── cypressAction.tsx │ │ ├── Assertion │ │ │ ├── Assertion copy.tsx │ │ │ ├── Assertion.module.scss │ │ │ ├── Assertion.tsx │ │ │ ├── AssertionMatchers.tsx │ │ │ ├── CypressAssertion.module.scss │ │ │ └── CypressAssertion.tsx │ │ ├── DescribeRenderer │ │ │ ├── DescribeRenderer.module.scss │ │ │ └── DescribeRenderer.tsx │ │ ├── ItRenderer │ │ │ ├── ItRenderer.module.scss │ │ │ └── ItRenderer.tsx │ │ ├── MockData │ │ │ ├── MockData.module.scss │ │ │ ├── MockData.tsx │ │ │ ├── MockDataKey.module.scss │ │ │ └── MockDataKey.tsx │ │ └── Render │ │ │ ├── Prop.module.scss │ │ │ ├── Prop.tsx │ │ │ ├── Render.module.scss │ │ │ ├── Render.tsx │ │ │ ├── Visit.module.scss │ │ │ └── Visit.tsx │ ├── ReduxTestComponent │ │ ├── ActionCreator │ │ │ ├── ActionCreator.module.scss │ │ │ └── ActionCreator.tsx │ │ ├── Middleware │ │ │ ├── Middleware.module.scss │ │ │ └── Middleware.tsx │ │ ├── Reducer │ │ │ ├── Reducer.module.scss │ │ │ └── Reducer.tsx │ │ └── Thunk │ │ │ ├── Thunk.module.scss │ │ │ └── Thunk.tsx │ ├── SearchInput │ │ ├── SearchInput.scss │ │ └── SearchInput.tsx │ ├── SolidTestComponent │ │ ├── Action │ │ │ └── Action.jsx │ │ ├── Assertion │ │ │ └── Assertion.jsx │ │ ├── DescribeRenderer │ │ │ └── DescribeRenderer.jsx │ │ ├── ItRenderer │ │ │ └── ItRenderer.jsx │ │ ├── MockData │ │ │ ├── MockData.jsx │ │ │ ├── MockData.module.scss │ │ │ ├── MockDataKey.jsx │ │ │ └── MockDataKey.module.scss │ │ └── Render │ │ │ ├── Prop.jsx │ │ │ └── Render.jsx │ ├── SvelteTestComponent │ │ ├── Action │ │ │ └── Action.jsx │ │ ├── Assertion │ │ │ └── Assertion.jsx │ │ ├── DescribeRenderer │ │ │ └── DescribeRenderer.jsx │ │ ├── ItRenderer │ │ │ └── ItRenderer.jsx │ │ ├── MockData │ │ │ ├── MockData.jsx │ │ │ ├── MockData.module.scss │ │ │ ├── MockDataKey.jsx │ │ │ └── MockDataKey.module.scss │ │ └── Render │ │ │ ├── Prop.jsx │ │ │ └── Render.jsx │ ├── Terminal │ │ ├── Terminal.css │ │ ├── TerminalView.tsx │ │ └── xterm.css │ ├── TestCase │ │ ├── AccTestCase.tsx │ │ ├── EndpointTestCase.tsx │ │ ├── EndpointTestStatements.tsx │ │ ├── GraphQLTestCase.tsx │ │ ├── GraphQLTestStatements.tsx │ │ ├── HooksTestCase.tsx │ │ ├── HooksTestStatements.tsx │ │ ├── PuppeteerTestCase.tsx │ │ ├── PuppeteerTestStatements.tsx │ │ ├── ReactContainer.module.scss │ │ ├── ReactTestCase.tsx │ │ ├── ReactTestStatements.tsx │ │ ├── ReduxTestCase.tsx │ │ ├── ReduxTestStatements.tsx │ │ ├── SecTestCase.tsx │ │ ├── SolidTestCase.jsx │ │ ├── SolidTestStatements.jsx │ │ ├── SvelteTestCase.jsx │ │ ├── SvelteTestStatements.jsx │ │ ├── TestCase.module.scss │ │ ├── TestFrameworkToggle.tsx │ │ ├── UpdatedReactTestCase.tsx │ │ ├── UpdatedReactTestStatements.tsx │ │ ├── VueTestCase.jsx │ │ ├── VueTestStatements.jsx │ │ └── importOptions.ts │ ├── TestMenu │ │ ├── AccTestMenu.tsx │ │ ├── EndpointTestMenu.tsx │ │ ├── GraphQLTestMenu.tsx │ │ ├── HooksTestMenu.tsx │ │ ├── PuppeteerTestMenu.tsx │ │ ├── ReactTestMenu.jsx │ │ ├── ReduxTestMenu.tsx │ │ ├── SecTestMenu.tsx │ │ ├── SolidTestMenu.jsx │ │ ├── SvelteTestMenu.jsx │ │ ├── TestMenu.module.scss │ │ ├── TestMenuButtons.jsx │ │ ├── UpdatedReactTestMenu.jsx │ │ ├── VueTestMenu.jsx │ │ ├── testMenuHooks.js │ │ └── updatedCypressReactComponent.tsx │ │ │ └── Statement │ │ │ └── CypressTestStatments.tsx │ ├── ToolTip │ │ ├── ToolTip.scss │ │ ├── ToolTip.tsx │ │ ├── ToolTipAsync.tsx │ │ └── ToolTipMatcher.tsx │ ├── TypesList │ │ ├── cypressMatcherTypeList.ts │ │ ├── cypressQueryActionTypesList.ts │ │ ├── cypressQuerySelectorTypesList.ts │ │ ├── eventTypesList.ts │ │ ├── matcherTypesList.ts │ │ ├── mochaMatcherTypesList.ts │ │ └── sinonMatcherTypesList.ts │ ├── UpdatedReactTestComponent │ │ ├── Action │ │ │ ├── Action.module.scss │ │ │ └── Action.tsx │ │ ├── Assertion │ │ │ ├── Assertion copy.tsx │ │ │ ├── Assertion.module.scss │ │ │ └── Assertion.tsx │ │ ├── DescribeBlock │ │ │ ├── DescribeBlock.tsx │ │ │ └── DescribeRenderer.module.scss │ │ ├── MockData │ │ │ ├── MockData.module.scss │ │ │ ├── MockData.tsx │ │ │ ├── MockDataKey.module.scss │ │ │ └── MockDataKey.tsx │ │ ├── Render │ │ │ ├── NOT_USED_Render.tsx │ │ │ ├── Prop.module.scss │ │ │ ├── Prop.tsx │ │ │ └── Render.module.scss │ │ ├── SetupTeardownBlock │ │ │ ├── SetupTeardownBlock.module.scss │ │ │ └── SetupTeardownBlock.tsx │ │ └── TestBlock │ │ │ ├── ItRenderer.module.scss │ │ │ └── TestBlock.tsx │ ├── UploadTest │ │ ├── UploadTest.module.scss │ │ └── UploadTest.ts │ ├── UserGuideView │ │ ├── Instructions.tsx │ │ ├── ReactInstructions.tsx │ │ ├── UserGuideView.module.scss │ │ └── UserGuideView.tsx │ └── VueTestComponent │ │ ├── Action │ │ └── Action.jsx │ │ ├── Assertion │ │ └── Assertion.jsx │ │ ├── DescribeRenderer │ │ └── DescribeRenderer.jsx │ │ ├── ItRenderer │ │ └── ItRenderer.jsx │ │ ├── MockData │ │ ├── MockData.jsx │ │ ├── MockData.module.scss │ │ ├── MockDataKey.jsx │ │ └── MockDataKey.module.scss │ │ └── Render │ │ ├── Prop.jsx │ │ └── Render.jsx ├── context │ ├── RTFsContextsProvider.tsx │ ├── actions │ │ ├── accTestCaseActions.ts │ │ ├── cypressTestCaseActions.ts │ │ ├── endpointTestCaseActions.ts │ │ ├── frontendFrameworkTestCaseActions.ts │ │ ├── globalActions.ts │ │ ├── graphQLTestCaseActions.ts │ │ ├── hooksTestCaseActions.ts │ │ ├── mockDataActions.ts │ │ ├── puppeteerTestCaseActions.ts │ │ ├── reduxTestCaseActions.ts │ │ ├── secTestCaseActions.ts │ │ └── updatedFrontendFrameworkTestCaseActions.ts │ ├── errorHandle │ │ ├── ConfirmDialogue.jsx │ │ └── ErrorBoundary.jsx │ ├── reducers │ │ ├── accTestCaseReducer.ts │ │ ├── cypressReactTestCaseReducer.ts │ │ ├── endpointTestCaseReducer.ts │ │ ├── globalReducer.ts │ │ ├── graphQLTestCaseReducer.ts │ │ ├── hooksTestCaseReducer.ts │ │ ├── mockDataReducer.ts │ │ ├── puppeteerTestCaseReducer.ts │ │ ├── reactTestCaseReducer.ts │ │ ├── reduxTestCaseReducer.ts │ │ ├── secTestCaseReducer.ts │ │ ├── solidTestCaseReducer.js │ │ ├── svelteTestCaseReducer.js │ │ ├── updatedMockDataReducer.ts │ │ ├── updatedReactTestCaseReducer.ts │ │ └── vueTestCaseReducer.js │ ├── updatedUseGenerateTest.jsx │ ├── useGenerateTest backup.jsx │ └── useGenerateTest.jsx ├── index.js ├── pages │ ├── LeftPanel │ │ ├── LeftPanel.jsx │ │ └── LeftPanel.module.scss │ ├── ProjectLoader │ │ ├── ProjectLoader.jsx │ │ └── ProjectLoader.module.scss │ ├── RightPanel │ │ ├── RightPanel.module.scss │ │ └── RightPanel.tsx │ └── TestFile │ │ ├── TestCard.jsx │ │ ├── TestCard.module.scss │ │ ├── TestFile.jsx │ │ └── TestFile.module.scss └── utils │ ├── accTypes.ts │ ├── endpointTypes.ts │ ├── globalTypes.ts │ ├── graphQLTypes.ts │ ├── hooksTypes.ts │ ├── mockTypes.ts │ ├── puppeteerTypes.ts │ ├── reactTestCase │ ├── cypress.ts │ ├── index.ts │ ├── matchers.ts │ ├── state.ts │ └── ui.ts │ ├── reduxTypes.ts │ ├── secTypes.ts │ ├── terminalTypes.ts │ ├── toolTipTypes.ts │ └── updatedReactTypes.ts ├── stats.json ├── temporaryDump ├── test └── mochaTest.js ├── tsconfig.json └── webpack.config.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | APP_DEV=true 2 | BROWSER=non 3 | SKIP_PREFLIGHT_CHECK=true 4 | MONGO_LINK=mongodb+srv://username:spearmint1234@cluster0.nzon2t8.mongodb.net/?retryWrites=true&w=majority -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "airbnb", 9 | "plugin:prettier/reccomended", 10 | "prettier/react" 11 | ], 12 | "root": true, 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaFeatures": { 16 | "jsx": true 17 | }, 18 | "ecmaVersion": "latest", 19 | "sourceType": "module" 20 | }, 21 | "plugins": [ 22 | "react", 23 | "@typescript-eslint" 24 | ], 25 | "rules": { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Test coverage directory 41 | coverage/ 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | package-lock.json 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variables file 76 | .env 77 | .env.test 78 | 79 | # parcel-bundler cache (https://parceljs.org/) 80 | .cache 81 | 82 | # Next.js build output 83 | .next 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Custom ignore files 111 | /out 112 | /build 113 | .DS_Store 114 | .dccache 115 | 116 | .env -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # use node version 16.13 2 | FROM node:16.13 3 | RUN apt-get update && apt-get install \ 4 | git libx11-xcb1 libxcb-dri3-0 libxshmfence-dev libdrm-dev \ 5 | libdrm2 libgconf2-dev libgbm-dev xvfb dbus-x11 libxtst6 \ 6 | libnss3 libatk-bridge2.0-0 libgtk-3-0 libxss1 libasound2 \ 7 | libudev-dev libgtkextra-dev libgbm1\ 8 | -yq --no-install-suggests --no-install-recommends \ 9 | && apt-get clean && rm -rf /var/lib/apt/lists/* 10 | 11 | RUN useradd -d /spearmint spearmint 12 | 13 | # root here to bypass permissions, not the best way to do this 14 | # USER spearmint 15 | USER root 16 | 17 | # WORKDIR sets the working directory for subsequent commands 18 | WORKDIR /spearmint 19 | 20 | COPY . . 21 | COPY package.json . 22 | 23 | # remove node modules from the file and only leave dependencies to be installed later 24 | RUN rm -rf node_modules 25 | # install node modules 26 | RUN npm install -force 27 | RUN npx electron-rebuild -f -w node-pty 28 | 29 | 30 | # EXPOSE port 3001 31 | EXPOSE 3001 32 | 33 | # Electron needs root for sandboxing 34 | # see https://github.com/electron/electron/issues/17972 35 | USER root 36 | RUN chown root /spearmint/node_modules/electron/dist/chrome-sandbox 37 | # adding additional layers to the image without deleteing the previos layer 38 | RUN chmod 4755 /spearmint/node_modules/electron/dist/chrome-sandbox 39 | 40 | # USER spearmint 41 | USER root 42 | CMD bash 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 spearmintjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ['@babel/preset-env', {targets: {node: 'current'}}], 4 | '@babel/preset-typescript', 5 | '@babel/preset-react', 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /declaration.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.scss' { 2 | const content: Record; 3 | export default content; 4 | } -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleNameMapper: { 3 | '\\.(css|scss)$': '/src/__tests__/styleMock.js', 4 | '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)':'/src/__tests__/styleMock.js', 5 | }, 6 | "collectCoverage": true, 7 | "collectCoverageFrom": [ 8 | "./src/components/**", 9 | "./src/context/**", 10 | "./src/pages/**", 11 | "./src/components/**", 12 | "./src/utils/**", 13 | "./src/**", 14 | "./public/**", 15 | "./server/**", 16 | "!**/*.json" 17 | ], 18 | "roots": [ 19 | "./src/__tests__", 20 | "./src", 21 | "./public", 22 | "./server", 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /public/LoadProjectDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/LoadProjectDemo.gif -------------------------------------------------------------------------------- /public/LoginDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/LoginDemo.gif -------------------------------------------------------------------------------- /public/RunDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/RunDemo.gif -------------------------------------------------------------------------------- /public/SaveDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/SaveDemo.gif -------------------------------------------------------------------------------- /public/ShowDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/ShowDemo.gif -------------------------------------------------------------------------------- /public/SpearmintGenerateTest.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/SpearmintGenerateTest.webp -------------------------------------------------------------------------------- /public/SpearmintRunTest.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/SpearmintRunTest.webp -------------------------------------------------------------------------------- /public/VcXsrv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/VcXsrv.png -------------------------------------------------------------------------------- /public/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/demo.png -------------------------------------------------------------------------------- /public/docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/docker.png -------------------------------------------------------------------------------- /public/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/icon.icns -------------------------------------------------------------------------------- /public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/icon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "spearmint", 3 | "name": "spearmint", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /public/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/moon.png -------------------------------------------------------------------------------- /public/openFolder.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/openFolder.webp -------------------------------------------------------------------------------- /public/saveTest.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/saveTest.webp -------------------------------------------------------------------------------- /public/spearmint_crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/spearmint_crop.png -------------------------------------------------------------------------------- /public/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/sun.png -------------------------------------------------------------------------------- /public/testingModal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/testingModal.png -------------------------------------------------------------------------------- /public/x410.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/public/x410.png -------------------------------------------------------------------------------- /server/controllers/cookieController.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | // import { NextFunction, Request, Response } from "express"; 5 | // import { cookieControllerType } from "../utils/backendTypes"; 6 | 7 | const cookieController /*: cookieControllerType*/ = {}; 8 | 9 | // Middleware to initialize a cookie when user logs in 10 | cookieController.setSSIDCookie = (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { 11 | // eslint-disable-next-line no-useless-escape 12 | //removing double quotes with Regex? 13 | res.cookie('ssid', JSON.stringify(res.locals.userId).replace(/\"/g, '')); 14 | return next(); 15 | }; 16 | 17 | // Middleware to delete a cookie upon user logging out 18 | cookieController.deleteCookie = (req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: void*/ => { 19 | res.clearCookie('ssid'); 20 | return next(); 21 | }; 22 | 23 | module.exports = cookieController; 24 | -------------------------------------------------------------------------------- /server/controllers/sessionController.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | // import { ErrorRequestHandler, NextFunction, Request, Response } from "express"; 5 | // import { MongoError, FindCursor } from "mongodb"; 6 | // import { sessionControllerType } from "../utils/backendTypes"; 7 | 8 | // Import the session model that defines schema of session 9 | const Session = require('../models/sessionModel'); 10 | 11 | const sessionController /*:sessionControllerType*/ = {}; 12 | 13 | // Middleware to initialize a session upon successful login 14 | sessionController.startSession = (req /* : Request */, res /* : Response */, next /* : NextFunction */) /* : void */ => { 15 | Session.create({ cookieId: res.locals.userId }, (err /* : MongoError */, result /* : void */) /* : void */ => { 16 | if (err && err.code !== 11000) return next(err); 17 | res.locals.ssid = res.locals.userId; 18 | return next(); 19 | }); 20 | }; 21 | 22 | // Middleware to end currently active sessions, if any 23 | sessionController.endSession = (req /* : Request */, res /*: Response */, next /* : NextFunction */)/*: void*/ => { 24 | Session.deleteMany({ cookieId: req.cookies.ssid }, (err /* : ErrorRequestHandler */) /* void */ => { 25 | if (err) return next(err); 26 | return next(); 27 | }); 28 | }; 29 | 30 | // Middleware to check if entered user is currently already logged in 31 | sessionController.isLoggedIn = (req /* :Request*/, res /* Response*/, next /* : NextFunction */) /* void */ => { 32 | Session.find({ cookieId: req.cookies.ssid }, (err /* : ErrorRequestHandler */, data /* : Array<{cookieId: String, createdAt: Date}> */) /* void */ => { 33 | if (err) return next(err); 34 | if (data.length === 0) return next('User Not Logged In'); 35 | return next(); 36 | }); 37 | }; 38 | 39 | module.exports = sessionController; 40 | -------------------------------------------------------------------------------- /server/controllers/testStateController.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | // import { ErrorRequestHandler, NextFunction, Request, Response } from "express"; 5 | // import { FindCursor } from "mongodb"; 6 | // import { testStateControllerType } from "../utils/backendTypes"; 7 | 8 | // Import test state model that defines the structure of test stored in DB 9 | const TestState = require('../models/testStateModel'); 10 | const testStateController /* :testStateControllerType */ = {}; 11 | 12 | // Middleware to upload a passed test into DB 13 | testStateController.upload = (req /* : Request */, res /* : Response */, next /* : NextFunction */) /* : void */ => { 14 | const { testName, testType, testState }/*: 15 | { testName : string, testType : string, testState : Object }*/ = req.body; 16 | const userId /* : number */ = req.cookies.ssid; 17 | 18 | TestState.create( 19 | { 20 | userId: String, 21 | testName: String, 22 | testType: String, 23 | testState: Object 24 | }, 25 | (err /* : Error */) /* : void */ => { 26 | if (err) return next('Upload Failed'); 27 | return next(); 28 | } 29 | ); 30 | }; 31 | 32 | // Middleware too get all saved tests of current user and of selected type 33 | testStateController.getTests = (req /* : Request */, res /* : Response */, next /* : NextFunction */) => { 34 | TestState.find({ userId: req.cookies.ssid, testType: req.params.testType }, (err /* : ErrorRequestHandler */, result /* : FindCursor */) /* : void */ => { 35 | // If an error occurs, invoke error handler with err object 36 | if (err) return next(err); 37 | // Save resulting tests array to locals object 38 | res.locals.tests = result; 39 | return next(); 40 | }); 41 | }; 42 | 43 | module.exports = testStateController; 44 | -------------------------------------------------------------------------------- /server/models/sessionModel.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | 5 | // import { Schema as SchemaType } from "mongoose"; 6 | 7 | // Import mongoose for MongoDB object modeling 8 | const mongoose = require('mongoose'); 9 | // Schema constructor 10 | const Schema = mongoose.Schema; 11 | 12 | // Initialize a new schema object for collection 'session' 13 | const sessionSchema/* : SchemaType */ = new Schema({ 14 | // Save user ID 15 | cookieId: { type: String, required: true, unique: true }, 16 | createdAt: { type: Date, default: Date.now }, 17 | }); 18 | 19 | module.exports = mongoose.model('Session', sessionSchema); 20 | -------------------------------------------------------------------------------- /server/models/testStateModel.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | 5 | //import { Schema as SchemaType } from "mongoose"; 6 | 7 | // Import mongoose for MongoDB object modeling 8 | const mongoose = require('mongoose'); 9 | // Schema constructor 10 | const Schema = mongoose.Schema; 11 | 12 | // Initialize a new schema object for collection 'testState' 13 | const testStateObj = { 14 | // Save ID of user that saves test 15 | userId: { type: String, required: true }, 16 | // Save name of test as user input 17 | testName: { type: String, required: true }, 18 | // Save corresponding type of test 19 | testType: { type: String, required: true }, 20 | // Save test state object 21 | testState: { type: Object, required: true }, 22 | }; 23 | 24 | 25 | // Initialize a new schema object for collection 'testState' 26 | const testStateSchema/* : SchemaType */ = new Schema(testStateObj); 27 | 28 | // Mongoose does not validate the types of the properties specified in schema 29 | // It will only coerce the properties to equal the types specified above 30 | // Therefore we use a pre-script to throw an error if any prop is the incorrect type, 31 | // preventing the uploading of documents with incorrect data type 32 | testStateSchema.pre('save', function(next) { 33 | if (typeof userId !== 'string' || 34 | typeof testName !== 'string' || 35 | typeof testType !== 'string' || 36 | typeof testState !== 'object') { 37 | return next('type failure'); 38 | } 39 | else return next(); 40 | }); 41 | 42 | module.exports = mongoose.model('testState', testStateSchema); 43 | -------------------------------------------------------------------------------- /server/models/userModel.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | 5 | // import { Schema as SchemaType } from "mongoose"; 6 | 7 | require('dotenv').config({ path: __dirname + '/./../../.env' }); 8 | // Import mongoose for MongoDB object modeling 9 | const mongoose = require('mongoose'); 10 | 11 | const MONGO_URI = process.env.MONGO_LINK; 12 | 13 | mongoose 14 | .connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }) 15 | .then(() => console.log('Connected to Mongo DB Successfully')) 16 | .catch((err) => console.log(err)); 17 | 18 | const Schema = mongoose.Schema; 19 | 20 | // Initialize a new schema object for collection 'user' 21 | const userSchema/*: SchemaType*/ = new Schema({ 22 | // Save username and password of user 23 | username: { type: String, require: true, unique: true }, 24 | password: { type: String, require: true }, 25 | }); 26 | 27 | const User/*: { username: String, password: String }*/ = mongoose.model('user', userSchema); 28 | 29 | const githubSchema/*: SchemaType*/ = new Schema({ 30 | // Save username and password of user 31 | githubId: { type: String, require: true, unique: true }, 32 | username: { type: String, require: true }, 33 | }); 34 | 35 | const GithubUser/*: { githubId: String, username: String }*/ = mongoose.model('githubUser', githubSchema); 36 | 37 | 38 | const googleSchema/*: SchemaType*/ = new Schema({ 39 | // Save username and password of user 40 | googleId: { type: String, require: true, unique: true }, 41 | username: { type: String, require: true }, 42 | }); 43 | 44 | const GoogleUser/*: { googleId: String, username: String }*/ = mongoose.model('googleUser', googleSchema); 45 | 46 | 47 | module.exports = { 48 | User, 49 | GithubUser, 50 | GoogleUser 51 | } 52 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | // import { Application, ErrorRequestHandler, NextFunction, Request, Response, Router } from "express"; 5 | // import { Authenticator } from "passport"; 6 | // import { defaultErrType } from "./utils/backendTypes"; 7 | 8 | const express = require('express'); 9 | const app/*: Application*/ = express(); 10 | const cookieParser/*: Function*/ = require('cookie-parser'); 11 | const router/*: Router*/ = require('./routes/router'); 12 | const PORT/*: number */= 3001; 13 | const passport/*: Authenticator*/ = require('passport'); 14 | 15 | // dotenv.config({ path: './config/config.env' }); 16 | require('./config/passport')(passport); 17 | 18 | app.use(express.json()); 19 | app.use(express.urlencoded({ extended: true })); 20 | app.use(cookieParser()); 21 | 22 | // Initialize passport session 23 | app.use(passport.initialize()); 24 | // app.use(passport.session()); 25 | 26 | app.use('/', router); 27 | 28 | // Any other request is caught here 29 | app.use((req/*: Request*/, res/*: Response*/)/*: Response*/ => res.status(404).send('Error 404: No content found')); 30 | 31 | // Express global error handler 32 | app.use((err/*: ErrorRequestHandler*/, req/*: Request*/, res/*: Response*/, next/*: NextFunction*/)/*: Response*/ => { 33 | const defaultErr/*: defaultErrType*/ = { 34 | log: 'Express error handler caught unknown middleware error', 35 | status: 500, 36 | message: 'An error occurred', 37 | }; 38 | const errorObj = Object.assign({}, defaultErr, err); 39 | return res.status(errorObj.status).json(err); 40 | }); 41 | 42 | // Start server 43 | app.listen(PORT, ()/*: void*/ => { 44 | console.log(`TEST Server listening on port: ${PORT}`); 45 | }); 46 | 47 | module.exports = app; 48 | module.exports = app; -------------------------------------------------------------------------------- /server/utils/backendTypes.ts: -------------------------------------------------------------------------------- 1 | /** using import statements in the electron / node files breaks npm start and nodepty 2 | * - types are left in place in these files for future iteration alternate import method is required for them to function 3 | */ 4 | 5 | //import { NextFunction, Request, Response } from "express"; 6 | 7 | const express = require('express') 8 | 9 | export interface defaultErrType { 10 | log: string, 11 | status: number, 12 | message: string, 13 | } 14 | 15 | export interface userControllerType { 16 | bcrypt: Function, 17 | signup: Function, 18 | login: Function, 19 | getUsers: Function, 20 | githubLogin: Function, 21 | googleLogin: Function, 22 | } 23 | 24 | export interface sessionControllerType { 25 | startSession?: Function, 26 | endSession?: Function, 27 | isLoggedIn?: Function, 28 | } 29 | 30 | export interface cookieControllerType { 31 | setSSIDCookie?: Function, 32 | deleteCookie?: Function, 33 | } 34 | 35 | export interface testStateControllerType { 36 | upload?: Function, 37 | getTests?: Function, 38 | } 39 | -------------------------------------------------------------------------------- /src/__tests__/Assertion.test.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import React from 'react'; 6 | import { render } from '@testing-library/react'; 7 | import '@testing-library/jest-dom/extend-expect'; 8 | import { ReactTestCaseContext } from '../context/reducers/reactTestCaseReducer'; 9 | import { MockDataContext } from '../context/reducers/mockDataReducer'; 10 | import Assertion from '../components/ReactTestComponent/Assertion/Assertion'; 11 | 12 | const dispatchToReactTextCase = jest.fn(); 13 | const dispatchToMockData = jest.fn(); 14 | 15 | const reactTestCaseState = { 16 | describeId: 'describe0', 17 | itId: 'it0', 18 | statementId: 'statement0', 19 | statement: { 20 | id: 'statement0', 21 | itId: 'it0', 22 | describeId: 'describe0', 23 | type: 'assertion', 24 | queryVariant: '', 25 | querySelector: '', 26 | queryValue: '', 27 | isNot: false, 28 | matcherType: '', 29 | matcherValue: '', 30 | suggestions: [], 31 | }, 32 | }; 33 | 34 | const mockDataState = { 35 | mockData: [], 36 | hasMockData: false, 37 | }; 38 | 39 | xdescribe('Assertion ', () => { 40 | it('renders without crashing', () => { 41 | // const div = document.createElement('div'); 42 | 43 | const { getByText, getAllByRole, debug } = render( 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | expect(getByText('Assertion')); 51 | 52 | expect(getAllByRole('textbox')).toBeInTheDocument; 53 | 54 | 55 | debug(); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /src/__tests__/EditorView.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import React from 'react'; 6 | import { render, screen, fireEvent } from '@testing-library/react'; 7 | import Editor from '../components/EditorView/EditorView'; 8 | import '@testing-library/jest-dom' 9 | 10 | describe('EditorView', () => { 11 | 12 | test('should render without crashing', () => { 13 | expect(render()).not.toBe(null); 14 | }); 15 | 16 | test('should render and display Code Editor', () => { 17 | render(); 18 | const codeEditor = screen.queryByTestId('Code Editor'); 19 | expect(codeEditor).toBeVisible(); 20 | }); 21 | 22 | test('button should display "Save Changes" ', () => { 23 | render(); 24 | const saveBtn = screen.queryByRole('button', {name: 'Save Changes'}); 25 | expect(saveBtn).toBeVisible(); 26 | }); 27 | 28 | test('button should display "Saved" after button click', () => { 29 | render(); 30 | const saveBtn = screen.queryByRole('button', {name: 'Save Changes'}); 31 | expect(saveBtn).not.toBe(null); 32 | fireEvent.click(saveBtn); 33 | const saved = screen.findByRole('button', {name: 'Saved'}); 34 | }); 35 | }); -------------------------------------------------------------------------------- /src/__tests__/Hooks.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import { renderHook, act, cleanup } from '@testing-library/react-hooks'; 6 | import useToggleModal from '../components/TestMenu/testMenuHooks'; 7 | 8 | afterEach(cleanup); 9 | xdescribe('Hooks testing', () => { 10 | test('hooks should render', () => { 11 | const { result } = renderHook(() => useToggleModal('redux')); 12 | expect(result.current.title).toBe('redux'); 13 | expect(result.current.isModalOpen).toBe(false); 14 | expect(typeof result.current.openModal).toBe('function'); 15 | }); 16 | 17 | test('openModal should work', () => { 18 | const { result } = renderHook(() => useToggleModal('redux')); 19 | 20 | act(() => { 21 | result.current.openModal(); 22 | }); 23 | expect(result.current.title).toBe('New Test'); 24 | expect(result.current.isModalOpen).toBe(true); 25 | }); 26 | 27 | test('openScriptModal should work', () => { 28 | const { result } = renderHook(() => useToggleModal('redux')); 29 | 30 | act(() => { 31 | result.current.openScriptModal(); 32 | }); 33 | expect(result.current.title).toBe('redux'); 34 | expect(result.current.isModalOpen).toBe(true); 35 | }); 36 | 37 | test('closeModal should work', () => { 38 | const { result } = renderHook(() => useToggleModal('redux')); 39 | 40 | act(() => { 41 | result.current.closeModal(); 42 | }); 43 | expect(result.current.title).toBe('redux'); 44 | expect(result.current.isModalOpen).toBe(false); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/__tests__/ModeSwitch.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import React from 'react'; 6 | import { render, screen, fireEvent } from '@testing-library/react'; 7 | import '@testing-library/jest-dom'; 8 | import ModeSwitch from '../components/ModeSwitch/ModeSwitch'; 9 | 10 | describe('ModeSwitch testing', () => { 11 | 12 | test('ModeSwitch should render without crashing', () => { 13 | expect(render()).not.toBe(null); 14 | }); 15 | 16 | test('ModeSwitch should render a dark mode icon', () => { 17 | render(); 18 | expect(screen.getByTitle('Dark Mode')).toBeVisible(); 19 | }); 20 | 21 | test('ModeSwitch should render a light mode icon', () => { 22 | render(); 23 | expect(screen.getByTitle('Light Mode')).toBeVisible(); 24 | }); 25 | 26 | // mode switch is checked by default 27 | test('User toggling mode switch should check or uncheck switch', async() => { 28 | render(); 29 | const toggle = screen.getByRole('checkbox'); 30 | expect(toggle.checked).toEqual(true); 31 | fireEvent.change(toggle, {target: {checked: false}}); 32 | expect(toggle.checked).toEqual(false); 33 | }); 34 | }); -------------------------------------------------------------------------------- /src/__tests__/ProjectLoaderTests/projectLoader.test.js: -------------------------------------------------------------------------------- 1 | it('displays browser view of when URL is correctly inputted', () => {}); 2 | 3 | it(`omitting 'www' from URL still displays browser view`, () => {}); 4 | 5 | it('displays file directory of project that is loaded', () => {}); 6 | 7 | it(`displays project's name on the top of the file directory view`, () => {}); 8 | -------------------------------------------------------------------------------- /src/__tests__/TestCard.test.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import React from 'react'; 6 | import { render, screen, fireEvent } from '@testing-library/react'; 7 | import '@testing-library/jest-dom'; 8 | import TestCard from '../pages/TestFile/TestCard'; 9 | 10 | const mockChooseTest = jest.fn(); 11 | 12 | describe('TestCard', () => { 13 | 14 | test('should render with correct text', () => { 15 | render(); 16 | expect(screen.getByText(/React/i)).toBeVisible(); 17 | }); 18 | 19 | test('should call choose test function after user click', () => { 20 | render(); 21 | const reactCard = screen.getByText(/React/i); 22 | fireEvent.click(reactCard); 23 | expect(mockChooseTest).toBeCalledTimes(1); 24 | }); 25 | }); -------------------------------------------------------------------------------- /src/__tests__/TestMenuButtons.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | 5 | import React from 'react'; 6 | import { render, screen, within, fireEvent } from '@testing-library/react'; 7 | import '@testing-library/jest-dom/extend-expect'; 8 | import TestMenuButtons from '../components/TestMenu/TestMenuButtons'; 9 | import userEvent from '@testing-library/user-event'; 10 | 11 | describe('should render the TestMenuButtons component', () => { 12 | it('displays the test menu component', () => { 13 | render(); 14 | screen.debug(); 15 | }); 16 | 17 | it('displays all five test menu buttons', () => { 18 | render(); 19 | const buttons = screen.getAllByRole('button'); 20 | 21 | expect(buttons).toHaveLength(5); 22 | expect(buttons).not.toBeNull(); 23 | 24 | buttons.forEach((button) => { 25 | const icon = within(button).getByTestId(/icon/i); 26 | expect(icon).toBeInTheDocument(); 27 | }); 28 | }); 29 | 30 | it('invokes resetTests, fileHandle, openScriptModal, saveTest, and openDocs functions on click', async () => { 31 | const props = { 32 | resetTests: jest.fn(), 33 | fileHandle: jest.fn(), 34 | openScriptModal: jest.fn(), 35 | saveTest: jest.fn(), 36 | openDocs: jest.fn(), 37 | }; 38 | render(); 39 | 40 | await userEvent.click(screen.getByTitle('New Test')); 41 | expect(props.resetTests).toHaveBeenCalledTimes(1); 42 | 43 | await userEvent.click(screen.getByTitle('Preview File')); 44 | expect(props.fileHandle).toHaveBeenCalledTimes(1); 45 | 46 | await userEvent.click(screen.getByTitle('Run File')); 47 | expect(props.openScriptModal).toHaveBeenCalledTimes(1); 48 | 49 | await userEvent.click(screen.getByTitle('Save File')); 50 | expect(props.saveTest).toHaveBeenCalledTimes(1); 51 | 52 | await userEvent.click(screen.getByTitle('Need Help?')); 53 | expect(props.openDocs).toHaveBeenCalledTimes(1); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /src/__tests__/spec.e2e.js: -------------------------------------------------------------------------------- 1 | const Application = require('spectron').Application; 2 | const path = require('path'); 3 | const chai = require('chai'); 4 | // const global = require('chai') 5 | const chaiAsPromised = require('chai-as-promised'); 6 | 7 | // specifies the path of the application to launch 8 | const electronPath = require('electron'); 9 | 10 | // tell spectron to look and use the main.js file + package.json located 2 levels above 11 | const appPath = path.join(__dirname, '../..'); 12 | 13 | 14 | // instantiates the spearmint application given the optional paramaters of the Application API 15 | const app = new Application({ 16 | path: electronPath, // string path to the Electron application executable to launch 17 | args: [appPath], // array of paths to find the executable files and package.json 18 | }); 19 | 20 | // define the use of chai and chai as promised packages 21 | // UNCOMMENT THE LINES BELOW TO UPDATE TESTING SUITE 22 | // global.before(function () { 23 | // chai.should(); 24 | // chai.use(chaiAsPromised); 25 | // }); 26 | 27 | xdescribe('Application Accessibility Audit', function () { 28 | this.timeout(10000); 29 | 30 | beforeEach(function () { 31 | return app.start(); 32 | }); 33 | 34 | afterEach(function () { 35 | if (app && app.isRunning()) { 36 | return app.stop(); 37 | } 38 | }); 39 | 40 | it('Audits Accessibility', function (done) { 41 | app.client.auditAccessibility().then(function (audit) { 42 | if (audit.failed) { 43 | console.error('Please address the following accessibility issues in your application: \n', audit.results) 44 | } 45 | else { 46 | console.log('No accessibility issues have been found.') 47 | } 48 | done() 49 | }) 50 | }); 51 | }); -------------------------------------------------------------------------------- /src/__tests__/spec.integra.js: -------------------------------------------------------------------------------- 1 | const Application = require('spectron').Application; 2 | const path = require('path'); 3 | 4 | // specifies the path of the application to launch 5 | const electronPath = require('electron'); 6 | 7 | // tell spectron to look and use the main.js file + package.json located 2 levels above 8 | const appPath = path.join(__dirname, '../..'); 9 | 10 | // instantiates the spearmint application given the optional paramaters of the Application API 11 | const app = new Application({ 12 | path: electronPath, // string path to the Electron application executable to launch 13 | args: [appPath], // array of paths to find the executable files and package.json 14 | }); 15 | 16 | 17 | describe('Application Accessibility Audit', function () { 18 | this.timeout(10000); 19 | // setTimeout(() => { 20 | // console.log('application is launching'); 21 | // }, 1000) 22 | 23 | beforeEach(function () { 24 | return app.start(); 25 | }); 26 | 27 | afterEach(function () { 28 | if (app && app.isRunning()) { 29 | return app.stop(); 30 | } 31 | }); 32 | 33 | it('Audits Accessibility', function () { 34 | return app.client.auditAccessibility().then(function (audit) { 35 | if (audit.failed) { 36 | console.error('Please address the following accessibility issues in your application: \n', audit.results) 37 | } 38 | else { 39 | console.log('No accessibility issues have been found.') 40 | } 41 | }) 42 | }); 43 | }); -------------------------------------------------------------------------------- /src/__tests__/spec.test.js: -------------------------------------------------------------------------------- 1 | const Application = require('spectron').Application; 2 | const assert = require('assert'); 3 | const electronPath = require('electron'); // Require Electron from the binaries included in node_modules. 4 | const path = require('path'); 5 | 6 | xdescribe('Application launch', function() { 7 | beforeEach(() => { 8 | this.app = new Application({ 9 | path: electronPath, 10 | args: [path.join(__dirname, '../../public/electron.js')], 11 | }); 12 | return this.app.start(); 13 | }); 14 | 15 | afterEach(() => { 16 | if (this.app && this.app.isRunning()) { 17 | return this.app.stop(); 18 | } 19 | }); 20 | 21 | test('shows an initial window', async () => { 22 | return this.app.client.getWindowCount().then(function(count) { 23 | assert.equal(count, 2); 24 | // Please note that getWindowCount() will return 2 if `dev tools` are opened. 25 | // assert.equal(count, 2) 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/__tests__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /src/__tests__/wdio.conf.js: -------------------------------------------------------------------------------- 1 | import url from 'node:url'; 2 | import path from 'node:path'; 3 | import fs from 'node:fs'; 4 | 5 | const exampleDir = process.env.EXAMPLE_DIR || 'forge-esm'; 6 | const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); 7 | const appDir = path.join(__dirname, '..', 'apps', exampleDir); 8 | const packageJsonPath = path.join(appDir, 'package.json'); 9 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, { encoding: 'utf-8' })); 10 | 11 | globalThis.packageJson = packageJson; 12 | process.env.TEST = 'true'; 13 | 14 | export const config = { 15 | 16 | services: [['electron', { rootDir, restoreMocks: true }]], 17 | capabilities: [ 18 | { 19 | 'browserName': 'electron', 20 | 'wdio:electronServiceOptions': { 21 | appArgs: ['foo', 'bar=baz'], 22 | }, 23 | }, 24 | ], 25 | 26 | waitforTimeout: 5000, 27 | connectionRetryCount: 2, 28 | connectionRetryTimeout: 30000, 29 | logLevel: 'debug', 30 | runner: 'local', 31 | outputDir: `wdio-logs-${exampleDir}`, 32 | specs: ['./test/js/*.spec.js'], 33 | framework: 'mocha', 34 | mochaOpts: { 35 | ui: 'bdd', 36 | timeout: 30000, 37 | }, 38 | }; -------------------------------------------------------------------------------- /src/assets/icons/add-black-18dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/close.png -------------------------------------------------------------------------------- /src/assets/images/content-save-outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/content-save-outline.png -------------------------------------------------------------------------------- /src/assets/images/describe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/describe.png -------------------------------------------------------------------------------- /src/assets/images/describe2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/describe2.png -------------------------------------------------------------------------------- /src/assets/images/describehelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/describehelp.png -------------------------------------------------------------------------------- /src/assets/images/drag-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/drag-vertical.png -------------------------------------------------------------------------------- /src/assets/images/file-document-outline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/file-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/file-export.png -------------------------------------------------------------------------------- /src/assets/images/folder-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/folder-open.png -------------------------------------------------------------------------------- /src/assets/images/folder-outline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/folder_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/folder_open.png -------------------------------------------------------------------------------- /src/assets/images/google-chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/google-chrome.png -------------------------------------------------------------------------------- /src/assets/images/help-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/help-circle.png -------------------------------------------------------------------------------- /src/assets/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/home.png -------------------------------------------------------------------------------- /src/assets/images/leaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/leaf.png -------------------------------------------------------------------------------- /src/assets/images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/menu.png -------------------------------------------------------------------------------- /src/assets/images/minus-box-outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/minus-box-outline.png -------------------------------------------------------------------------------- /src/assets/images/newReact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/newReact.png -------------------------------------------------------------------------------- /src/assets/images/plus-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/plus-box.png -------------------------------------------------------------------------------- /src/assets/images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/plus.png -------------------------------------------------------------------------------- /src/assets/images/spearmintHomepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/spearmintHomepage.png -------------------------------------------------------------------------------- /src/assets/images/testfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/testfile.png -------------------------------------------------------------------------------- /src/assets/images/visual-studio-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/src/assets/images/visual-studio-code.png -------------------------------------------------------------------------------- /src/assets/stylesheets/colors.scss: -------------------------------------------------------------------------------- 1 | 2 | // color palette light 3 | 4 | $mint: #24A19C; 5 | $lighter-mint: #24A19Caf;//darken($mint, 10%); 6 | $eggshell: #f8f6f6; 7 | $eggshell-opaque: #f8f6f6a4; 8 | $darkslategrey: darkslategrey; 9 | $lighttext: #bdc1c6; 10 | $chromegray: #303134; 11 | $chromegray-less-light: lighten(#303134, 5%); 12 | $chromegray-light: lighten(#303134, 10%); 13 | $chromegray-lighter: lighten(#303134, 15%); 14 | $chromegray-opaque: #303134d7; 15 | 16 | $navy: #325288; 17 | $salmon: #8f54a0; 18 | $salmon-darker: #7c4a8a; 19 | 20 | $mint2: #02c3c33f; 21 | $mint3: #0fa9a95c; 22 | $dark-gray: #808080; 23 | $light-gray: #d5d5d5; 24 | $light-gray2: #f6f8f9; 25 | $light-gray3: #fafcfc; 26 | $light-gray4: #bceeeed7; 27 | 28 | /* original colors 29 | $salmon: #8f54a0; 30 | $salmon-darker: #7c4a8a; 31 | $eggshell: #f2f2f2; 32 | $eggshell-opaque: #F1F3F4a4; 33 | $mint: #24A19C; 34 | $lighter-mint: #24A19Caf;//darken($mint, 10%); 35 | */ -------------------------------------------------------------------------------- /src/assets/stylesheets/fonts.scss: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Comfortaa|Open+Sans|Raleway|Oxygen|Roboto&display=swap); 2 | 3 | $comfortaa: 'Comfortaa', cursive; 4 | $openSans: 'Open Sans', sans-serif; 5 | $oxygen: 'Oxygen', sans-serif; 6 | $raleway: 'Raleway', sans-serif; 7 | $roboto: 'Roboto', sans-serif; -------------------------------------------------------------------------------- /src/assets/stylesheets/global.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | * { 5 | box-sizing: border-box; 6 | transition: background-color .75s ease, color 0.5s ease; 7 | // overflow: hidden; 8 | } 9 | 10 | /* ===== Scrollbar CSS ===== */ 11 | /* Firefox */ 12 | // * { 13 | // scrollbar-width: none; 14 | // scrollbar-color: #8f54a0 #ffffff; 15 | // } 16 | 17 | /* Chrome, Edge, and Safari */ 18 | *::-webkit-scrollbar { 19 | width: 9px; 20 | height: 9px; 21 | } 22 | 23 | *::-webkit-scrollbar-track { 24 | background: black; 25 | border-radius: 10px; 26 | } 27 | 28 | *::-webkit-scrollbar-thumb { 29 | background-color: #8f54a0; 30 | border-radius: 10px; 31 | } 32 | 33 | html, 34 | body{ 35 | height: 100%; 36 | } 37 | 38 | #contents { 39 | overflow-y: overlay; 40 | } 41 | 42 | html { 43 | font-size: 62.5%; 44 | background-color: white; 45 | } 46 | 47 | body{ 48 | font-family: $comfortaa; 49 | font-size: 1rem; 50 | letter-spacing: 0.02857em; 51 | } 52 | 53 | a { 54 | text-decoration: none; 55 | } 56 | 57 | button:hover { 58 | box-shadow: inset 0em 0em 0em 10em rgba(0, 0, 0, 0.3); 59 | } 60 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/AccTestTypes/AccTestTypes.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | 3 | #AccTestTypesComponent{ 4 | margin-right: 35px; 5 | } 6 | 7 | #AccTestTypesLabel { 8 | display: block; 9 | margin-bottom: 6px; 10 | font-family: $oxygen; 11 | font-size: 14px; 12 | } 13 | 14 | .AccTestTypesInput{ 15 | margin-top: 4px; 16 | min-height: 35px; 17 | } -------------------------------------------------------------------------------- /src/components/AccTestComponent/AccTestTypes/AccTestTypes.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import styles from './AccTestTypes.module.scss'; 4 | 5 | 6 | /** 7 | * Renders the dropdown menu to 'Choose Type of Accessibility Test' inside the Accessibility TestType. 8 | * @returns { JSX.Element } Returns the AccTestTypes react component 9 | */ 10 | 11 | 12 | const AccTestTypes = (prop: any) => { 13 | 14 | const { action, dispatch} = prop; 15 | 16 | const handleChange = (event: any) => { 17 | if (action) dispatch(action(event.target.value)); 18 | } 19 | 20 | return ( 21 |
22 | 25 | 36 |
37 | ); 38 | }; 39 | 40 | export default AccTestTypes; 41 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/CatTagFilter/CatTagFilter.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | 4 | #CatTagFilter { 5 | font-weight: bold; 6 | font-size: 0.75rem; 7 | position: relative; 8 | margin-left: 5px; 9 | margin-top: 10px; 10 | z-index: 3; 11 | 12 | #accTestCatTypes:focus { 13 | border: 2px solid darkblue; 14 | } 15 | } -------------------------------------------------------------------------------- /src/components/AccTestComponent/CatTagFilter/CatTagFilter.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './CatTagFilter.module.scss'; 3 | 4 | interface CatTagFilterTypes { 5 | dispatch: Function, 6 | tagAction: object, 7 | textAction: object, 8 | itId: number, 9 | catTag: string, 10 | } 11 | 12 | /** 13 | * Renders the dropdown menu to 'Choose A Content Filter' inside the Accessibility TestType. 14 | * @param { prop } dispatch - 15 | * @param { prop } tagAction - 16 | * @param { prop } textAction - 17 | * @param { prop } itId - number 18 | * @param { prop } catTag string 19 | * @returns { JSX.Element } Returns the CatTagFilter react component 20 | */ 21 | const CatTagFilter = ({ dispatch, tagAction, textAction, itId, catTag }): JSX.Element => { 22 | const handleChange = (e: React.ChangeEvent) => { 23 | dispatch(tagAction(itId, e.target.value)); 24 | if (e.target.value === 'none') dispatch(textAction(`Component is accessible regarding all axe-core categories.`, itId)); 25 | else dispatch(textAction(`Component is accessible regarding ${e.target.value}.`, itId)); 26 | }; 27 | 28 | return ( 29 |
30 | 31 | 47 |
48 | ); 49 | }; 50 | 51 | export default CatTagFilter; 52 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/DescribeRenderer/DescribeRenderer.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #describeBlock { 6 | min-width: 50vw; 7 | position: relative; 8 | background-color: white; 9 | border-radius: 3px; 10 | padding: 1rem; 11 | margin-top: 10px; 12 | box-shadow: 1px 1px 5px gray; 13 | display: flex; 14 | flex-direction: column; 15 | z-index: 0; 16 | 17 | .describeClose { 18 | position: absolute; 19 | top: 5px; 20 | right: 5px; 21 | font-size: 1.25rem; 22 | z-index: 3; 23 | transition: 250ms; 24 | 25 | &:hover { 26 | color: red; 27 | cursor: pointer; 28 | font-size: 1.5rem; 29 | font-weight: bold; 30 | } 31 | } 32 | 33 | .separator { 34 | position: absolute; 35 | top: 0; 36 | left: 0; 37 | width: 100%; 38 | height: 100px; 39 | // background-color: rgba(128, 128, 128, 0.20); 40 | background-color: #02c3c33f; 41 | border-bottom: 2px solid gray; 42 | opacity: 100%; 43 | z-index: 0; 44 | } 45 | 46 | .describeLabel { 47 | font-weight: bold; 48 | font-size: 1rem; 49 | z-index: 3; 50 | font-family: $oxygen; 51 | } 52 | 53 | .describeStatement { 54 | border: none; 55 | border-bottom: 1px solid $mint; 56 | background-color: rgba(0, 0, 0, 0); 57 | margin-top: .8rem; 58 | margin-bottom: .8rem; 59 | font-size: 0.9rem; 60 | z-index: 3; 61 | } 62 | 63 | .buttonContainer { 64 | display: flex; 65 | justify-content: center; 66 | align-items: center; 67 | height: 30px; 68 | margin-top: 1rem; 69 | 70 | .addIt { 71 | height: auto; 72 | color: white; 73 | padding: 0.5rem; 74 | border-radius: 5px; 75 | background-color: $mint; 76 | border: none; 77 | 78 | &:hover { 79 | background-color: white; 80 | color: $mint; 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/ItRenderer/ItRenderer.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | 4 | #ItRenderer { 5 | position: relative; 6 | display: flex; 7 | flex-direction: column; 8 | margin-top: 1.5rem; 9 | padding: 0.5rem; 10 | background-color: $light-gray2; 11 | border-radius: 3px; 12 | box-shadow: 2px 2px 5px gray; 13 | height: 100px; 14 | 15 | .itClose { 16 | position: absolute; 17 | font-size: 1.25rem; 18 | top: 5px; 19 | right: 5px; 20 | transition: 250ms; 21 | cursor: pointer; 22 | z-index: 3; 23 | 24 | &:hover { 25 | color: red; 26 | font-size: 1.5rem; 27 | font-weight: bold; 28 | } 29 | } 30 | 31 | .itStatement { 32 | position: absolute; 33 | bottom: 15px; 34 | width: 97.4%; 35 | padding: 0.1rem; 36 | padding-left: 0.4rem; 37 | font-size: 1.1em; 38 | border-bottom: 1px solid $mint; 39 | background-color: rgba(0, 0, 0, 0); 40 | } 41 | 42 | .buttonsContainer { 43 | margin-top: 1rem; 44 | display: flex; 45 | justify-content: space-evenly; 46 | align-items: center; 47 | } 48 | 49 | .reactButton { 50 | height: auto; 51 | font-size: 1rem; 52 | background-color: rgba(0, 0, 0, 0); 53 | border: none; 54 | min-width: 150px; 55 | border-radius: 3px; 56 | font-family: $oxygen; 57 | text-align: center; 58 | transition: 150ms; 59 | color: $mint; 60 | 61 | &:hover { 62 | font-size: 1.1rem; 63 | } 64 | 65 | i { 66 | margin-right: 0.5rem; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/ItRenderer/ItRenderer.tsx: -------------------------------------------------------------------------------- 1 | import React, { ChangeEvent, useContext } from 'react'; 2 | import cn from 'classnames'; 3 | import { AccTestCaseContext } from '../../../context/reducers/accTestCaseReducer'; 4 | import CatTagFilter from '../CatTagFilter/CatTagFilter'; 5 | import { AiOutlineClose } from 'react-icons/ai'; 6 | 7 | import { deleteItStatement } from '../../../context/actions/accTestCaseActions'; 8 | 9 | import styles from './ItRenderer.module.scss'; 10 | /** 11 | * Renders the ItRenderer react compoonent that allows 12 | * the users to create it statements for Accessibility 13 | * @returns { JSX.Element } Returns the DescribeRenderer component 14 | */ 15 | const ItRenderer = ({ 16 | itStatements, 17 | describeId, 18 | updateItStatementText, 19 | updateItCatTag, 20 | }) => { 21 | const [, dispatchToAccTestCase] = useContext(AccTestCaseContext); 22 | 23 | /** 24 | * Function that on click, deletes a It statement 25 | * @param { e } e - event 26 | * @returns { void } Returns void 27 | */ 28 | const deleteItStatementHandleClick = (e: ChangeEvent) => { 29 | const itId = e.currentTarget.id; 30 | dispatchToAccTestCase(deleteItStatement(describeId, itId)); 31 | }; 32 | /** 33 | * Deletes the statement block in Accessibility test type when the charCode 13 (ENTER) is pressed. 34 | * 35 | * NOTE: This functionality doesn't seem to be working at the moment. 36 | * @param { e } e - event 37 | * @returns { void } Returns void 38 | */ 39 | 40 | const deleteItStatementOnKeyUp = (e) => { 41 | if (e.charCode === 13) { 42 | const itId = e.currentTarget.id; 43 | dispatchToAccTestCase(deleteItStatement(describeId, itId)); 44 | } 45 | }; 46 | 47 | return itStatements.allIds[describeId].map((id: string, i: number) => { 48 | return ( 49 |
50 | 57 | 58 | 65 | 66 |

{itStatements.byId[id].text}

67 |
68 |
69 | ); 70 | }); 71 | }; 72 | 73 | export default ItRenderer; 74 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/PuppeteerUrl/PuppeteerUrl.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // import styles used in AccTestTypes for input labels et al. 3 | import styles from '../AccTestTypes/AccTestTypes.module.scss'; 4 | 5 | 6 | /** 7 | * Renders the AccTestTypes react component 8 | * 9 | * @property { Function } dispatch - description 10 | * @property { object } action - description 11 | * @return { JSX.Element } Returns the AccTestTypes react component 12 | */ 13 | const AccTestTypes = ({ dispatch, action }) => { 14 | const handleChange = (e: React.ChangeEvent) => { 15 | dispatch(action(e.target.value)); 16 | }; 17 | 18 | return ( 19 |
20 | 21 | 22 | 23 |
24 | ); 25 | }; 26 | 27 | export default AccTestTypes; 28 | -------------------------------------------------------------------------------- /src/components/AccTestComponent/StandardTagFilter/StandardTagFilter.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | 4 | #StandardTagFilter { 5 | font-weight: bold; 6 | font-size: 0.8rem; 7 | position: relative; 8 | margin-top: 10px; 9 | z-index: 3; 10 | 11 | #accTestStandardTypes:focus { 12 | border: 2px solid darkblue; 13 | } 14 | } -------------------------------------------------------------------------------- /src/components/AccTestComponent/StandardTagFilter/StandardTagFilter.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './StandardTagFilter.module.scss'; 3 | 4 | /** 5 | * Renders the StandardTagFilter react component, this is a dropdown menu in the DescribeBlock accessibility standard 6 | * @property { } dispatch 7 | * @property { } tagAction 8 | * @property { } textAction 9 | * @property { } describeID 10 | * @property { } standardTag 11 | * @returns { JSX.Element } Returns the StandardTagFilter react component 12 | */ 13 | const StandardTagFilter = ({ dispatch, tagAction, textAction, describeId, standardTag }) => { 14 | const handleChange = (e: React.ChangeEvent) => { 15 | dispatch(tagAction(describeId, e.target.value)); 16 | if (e.target.value === 'none') dispatch(textAction(`Component is accessible according to all standards enforced by axe-core.`, describeId)); 17 | else dispatch(textAction(`Component is accessible according to ${e.target.value} standards.`, describeId)); 18 | }; 19 | 20 | return ( 21 |
22 | 23 | 34 |
35 | ); 36 | }; 37 | 38 | export default StandardTagFilter; 39 | -------------------------------------------------------------------------------- /src/components/AutoComplete/AutoComplete.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | .container { 5 | position: relative; 6 | } 7 | 8 | .input { 9 | width: 185px; 10 | font-family: $oxygen; 11 | font-weight: 300; 12 | font-size: 12; 13 | color: black; 14 | } 15 | 16 | .inputFocused { 17 | outline: none; 18 | } 19 | 20 | .inputOpen { 21 | border-bottom-left-radius: 0; 22 | border-bottom-right-radius: 0; 23 | } 24 | 25 | .suggestionsContainer { 26 | display: none; 27 | } 28 | 29 | .suggestionsContainerOpen { 30 | display: block; 31 | position: absolute; 32 | top: 26px; 33 | width: 100%; 34 | border: 1px solid $light-gray; 35 | background-color: #fff; 36 | font-family: $oxygen; 37 | font-weight: 300; 38 | letter-spacing: 0.5px; 39 | font-size: 16px; 40 | border-radius: 0 0 4px 4px; 41 | z-index: 2; 42 | } 43 | 44 | .suggestionsList { 45 | margin: 0; 46 | padding: 0; 47 | list-style-type: none; 48 | height: 200px; 49 | overflow-y: scroll; 50 | 51 | color: black; 52 | 53 | } 54 | 55 | .suggestion { 56 | cursor: pointer; 57 | padding: 10px 20px; 58 | } 59 | 60 | .suggestionHighlighted { 61 | background-color: $light-gray4; 62 | } 63 | -------------------------------------------------------------------------------- /src/components/AutoComplete/AutoCompleteMockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | .container { 5 | position: relative; 6 | } 7 | 8 | .input { 9 | // width: 185px; 10 | width: 185px; 11 | padding: '10px 20px'; 12 | font-family: $oxygen; 13 | font-weight: 300; 14 | font-size: 12; 15 | letter-spacing: 0.5px; 16 | background-color: red($color: #ed0909); 17 | border: '1px solid #aaa'; 18 | } 19 | 20 | .inputFocused { 21 | outline: none; 22 | } 23 | 24 | .inputOpen { 25 | border-bottom-left-radius: 0; 26 | border-bottom-right-radius: 0; 27 | } 28 | 29 | .suggestionsContainer { 30 | display: none; 31 | } 32 | 33 | .suggestionsContainerOpen { 34 | display: block; 35 | position: absolute; 36 | top: 26px; 37 | width: 185px; 38 | border: 1px solid $light-gray; 39 | background-color: #fff; 40 | font-family: $oxygen; 41 | font-weight: 300; 42 | letter-spacing: 0.5px; 43 | font-size: 16px; 44 | border-radius: 0 0 4px 4px; 45 | z-index: 2; 46 | } 47 | 48 | .suggestionsList { 49 | margin: 0; 50 | padding: 0; 51 | list-style-type: none; 52 | height: 200px; 53 | overflow-y: scroll; 54 | } 55 | 56 | .suggestion { 57 | cursor: pointer; 58 | padding: 10px 20px; 59 | } 60 | 61 | .suggestionHighlighted { 62 | background-color: $light-gray4; 63 | } 64 | -------------------------------------------------------------------------------- /src/components/BrowserView/BrowserView.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | #browserComponentTopLevelDivlight{ 5 | margin-top: 1px; 6 | display: flex; 7 | flex-direction: column; 8 | * { 9 | font-size: 0.75rem; 10 | font-family: 'comfortaa'; 11 | } 12 | height: 100%; 13 | 14 | --label-color: #{$mint}; 15 | --box-bg: #{$mint2}; 16 | --box-color: black; 17 | } 18 | 19 | #browserComponentTopLevelDivdark{ 20 | margin-top: 1px; 21 | display: flex; 22 | flex-direction: column; 23 | * { 24 | font-size: 0.75rem; 25 | font-family: 'comfortaa'; 26 | } 27 | height: 100%; 28 | --label-color: #{$darkslategrey}; 29 | --box-bg: #{$chromegray}; 30 | --box-color: #{$eggshell}; 31 | } 32 | 33 | #accessLensContainer{ 34 | display: flex; 35 | flex-direction: column; 36 | width: 100%; 37 | justify-content: center; 38 | } 39 | 40 | #accessLensLabel { 41 | display: flex; 42 | justify-content: center; 43 | align-items: center; 44 | background-color: var(--label-color); 45 | color: $eggshell; 46 | font-size: 1rem; 47 | height: auto; 48 | width: 100%; 49 | border: transparent; 50 | border-style: solid; 51 | padding: 5px 10px; 52 | * { 53 | flex: 1; 54 | } 55 | } 56 | 57 | #accessLensCheckBoxes{ 58 | padding: 0 5px; 59 | display: grid; 60 | grid-template-columns: repeat(4, 1fr); 61 | grid-template-rows: repeat(2, 1fr); 62 | background-color: var(--box-bg); 63 | //border: $mint2; 64 | border: transparent; 65 | border-width: .05em; 66 | border-style: solid; 67 | *{ 68 | transition: color 0.0s !important; 69 | color: var(--box-color); 70 | } 71 | } 72 | 73 | #browserBar { 74 | width: 100%; 75 | padding: 5px; 76 | background-color: $chromegray; 77 | } 78 | 79 | #browserAddress { 80 | width: 100%; 81 | padding: 8px; 82 | background-color: $chromegray-light; 83 | color: white; 84 | border: transparent; 85 | border-radius: 5px; 86 | 87 | &::placeholder { 88 | color: $eggshell-opaque; 89 | } 90 | } 91 | 92 | #browserView { 93 | height: 100%; 94 | } 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/components/CypressTestCase.tsx: -------------------------------------------------------------------------------- 1 | // frontend for Cypress test cases for frontend frameworks 2 | 3 | 4 | 5 | // Build dummy UI with 1 "visit" step first (MVP) -------------------------------------------------------------------------------- /src/components/EditorView/EditorView.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | #codeEditor{ 5 | * { 6 | transition: color 0.0s !important; 7 | } 8 | } 9 | 10 | #saveBox{ 11 | flex: 0 0 5%; 12 | } 13 | 14 | #btn { 15 | height: 38px; 16 | width: 100% !important; 17 | color: white; 18 | background-color: #{$salmon}; 19 | font-family: $raleway; 20 | font-weight: bold; 21 | font-size: 14px; 22 | border-radius: 5px; 23 | border: 0.5px $light-gray solid; 24 | } 25 | 26 | #save:hover { 27 | background-color: rgb(180, 180, 180); 28 | color: white; 29 | border-radius: 5px; 30 | } 31 | 32 | #span { 33 | font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 34 | 'Apple Color Emoji', 'Segoe UI Emoji'; 35 | line-height: 1.5; 36 | position: relative; 37 | color:white; 38 | } 39 | -------------------------------------------------------------------------------- /src/components/EndpointTestComponent/JestMatchers.ts: -------------------------------------------------------------------------------- 1 | const jestMatchers: string[] = [ 2 | '', 3 | 'to Be', 4 | 'to Equal (object)', 5 | 'to Have Been Called', 6 | 'to Have Been Called Times (number)', 7 | 'to Have Been Called With (arg1,...)', 8 | 'to Have Been Last Called With (arg1,...)', 9 | 'to Have Been Nth Called With (nth call, arg1,...)', 10 | 'to Have Length (number)', 11 | 'to Have Property (keyPath, value[optional])', 12 | 'to Be Close To (number, number of digits[optional])', 13 | 'to Be Defined', 14 | 'to Be Undefined', 15 | 'to Be Falsy', 16 | 'to Be Truthy', 17 | 'to Be NaN', 18 | 'to Be Greater Than (number)', 19 | 'to Be Greater Than Or Equal (number)', 20 | 'to Be Less Than (number)', 21 | 'to Be Less Than Or Equal (number)', 22 | 'to Be Instance Of (Class)', 23 | 'to Contain (item in an array)', 24 | 'to Contain Equal (an object in an array)', 25 | 'to Match (regexp or string)', 26 | 'to Match Object (object)', 27 | 'to Strict Equal (object)', 28 | 'to Throw (error[optional])', 29 | ]; 30 | 31 | //for mock fuctions only: 32 | // 'to Have Returned', 33 | // 'to Have Returned __ Times (number)', 34 | // 'to Have Last Returned With', 35 | // ]; 36 | 37 | export default jestMatchers; 38 | -------------------------------------------------------------------------------- /src/components/FileDirectory/FileDirectory.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | #fileDirectory { 5 | 6 | flex: 0 1 200px; 7 | min-width: 150px; 8 | //max-height: 90vh; 9 | font-size: 12px; 10 | background-color: var(--fileDir-bg); 11 | overflow: auto; 12 | z-index: 1; 13 | border-radius: 5px; 14 | //overflow: scroll; 15 | 16 | ul { 17 | list-style-type: none; 18 | padding-left: 10px; 19 | text-align: left; 20 | 21 | *{ 22 | transition: none !important; 23 | } 24 | } 25 | li { 26 | text-align: left; 27 | padding: 3px; 28 | } 29 | button { 30 | display: flex; 31 | align-items: center; 32 | gap: 5px; 33 | width: 100%; 34 | 35 | svg { 36 | flex: 0 0 16px; 37 | } 38 | 39 | span { 40 | flex: 1; 41 | } 42 | 43 | } 44 | 45 | #explorer { 46 | position: sticky; 47 | top: 0; 48 | padding: 10px; 49 | color: $eggshell; 50 | font-family: $oxygen; 51 | font-weight: 600; 52 | background-color: $salmon; 53 | } 54 | } 55 | 56 | #fileTreeContainer{ 57 | padding-top: 10px; 58 | display: flex; 59 | flex-direction: column; 60 | gap: 3px; 61 | } 62 | 63 | #file { 64 | width: 18px; 65 | height: 18px; 66 | margin-right: 6px; 67 | float: left; 68 | } 69 | 70 | #folder { 71 | padding-right: 6px; 72 | } 73 | 74 | #dirButton { 75 | text-decoration: none; 76 | color: $eggshell; 77 | background-color: transparent; 78 | border: none; 79 | font-family: $oxygen; 80 | text-align: left; 81 | vertical-align: middle; 82 | width: 100%; 83 | padding: 3px 0 3px 3px; 84 | border-radius: 2px; 85 | transition: none !important; 86 | } 87 | 88 | #dirButton:hover { 89 | background-color: var(--dir-button-bg); 90 | color: var(--dir-button-color); 91 | } 92 | 93 | #dirButtonHilighted { 94 | transition: none !important; 95 | text-align: left; 96 | font-family: $oxygen; 97 | background-color: var(--dir-button-bg); 98 | border: none; 99 | color: var(--dir-button-color); 100 | box-shadow: inset 0em 0em 0em 10em rgba(0, 0, 0, 0.3); 101 | padding: 3px 0 3px 3px; 102 | border-radius: 2px; 103 | width: 100%; 104 | } 105 | -------------------------------------------------------------------------------- /src/components/GraphQLTestComponent/JestMatchers.ts: -------------------------------------------------------------------------------- 1 | const jestMatchers: string[] = [ 2 | '', 3 | 'to Be', 4 | 'to Equal (object)', 5 | 'to Have Been Called', 6 | 'to Have Been Called Times (number)', 7 | 'to Have Been Called With (arg1,...)', 8 | 'to Have Been Last Called With (arg1,...)', 9 | 'to Have Been Nth Called With (nth call, arg1,...)', 10 | 'to Have Length (number)', 11 | 'to Have Property (keyPath, value[optional])', 12 | 'to Be Close To (number, number of digits[optional])', 13 | 'to Be Defined', 14 | 'to Be Undefined', 15 | 'to Be Falsy', 16 | 'to Be Truthy', 17 | 'to Be NaN', 18 | 'to Be Greater Than (number)', 19 | 'to Be Greater Than Or Equal (number)', 20 | 'to Be Less Than (number)', 21 | 'to Be Less Than Or Equal (number)', 22 | 'to Be Instance Of (Class)', 23 | 'to Contain (item in an array)', 24 | 'to Contain Equal (an object in an array)', 25 | 'to Match (regexp or string)', 26 | 'to Match Object (object)', 27 | 'to Srict Equal (object)', 28 | 'to Throw (error[optional])', 29 | ]; 30 | 31 | //for mock fuctions only: 32 | // 'to Have Returned', 33 | // 'to Have Returned __ Times (number)', 34 | // 'to Have Last Returned With', 35 | // ]; 36 | 37 | export default jestMatchers; 38 | -------------------------------------------------------------------------------- /src/components/InputTextField.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import withStyles from '@mui/styles/withStyles'; 3 | import { TextField } from '@mui/material'; 4 | import { GlobalContext } from '../context/reducers/globalReducer'; 5 | 6 | const CssTextFieldLight = withStyles({ 7 | root: { 8 | '& .MuiOutlinedInput-root': { 9 | '& fieldset': { 10 | borderColor: 'black', //theme === 'light' ? '#fff' : 'black', 11 | }, 12 | '&:hover fieldset': { 13 | borderColor: 'green', 14 | }, 15 | '&.Mui-focused fieldset': { 16 | borderColor: '#8f54a0', 17 | }, 18 | '& label.Mui-focused': { 19 | color: '#8f54a0', 20 | }, 21 | '& .MuiInput-underline:after': { 22 | borderBottomColor: '#8f54a0', 23 | }, 24 | }, 25 | }, 26 | })(TextField); 27 | 28 | const CssTextFieldDark = withStyles({ 29 | root: { 30 | '& .MuiOutlinedInput-root': { 31 | '& fieldset': { 32 | borderColor: '#fff', //theme === 'light' ? '#fff' : 'black', 33 | }, 34 | '&:hover fieldset': { 35 | borderColor: '#fff', 36 | }, 37 | '&.Mui-focused fieldset': { 38 | borderColor: '#8f54a0', 39 | }, 40 | '& label.Mui-focused': { 41 | color: '#8f54a0', 42 | }, 43 | '& .MuiInput-underline:after': { 44 | borderBottomColor: '#8f54a0', 45 | }, 46 | }, 47 | }, 48 | })(TextField); 49 | 50 | 51 | const InputTextField = (props) => { 52 | const [{ theme }] = useContext(GlobalContext); 53 | 54 | if (theme === 'light'){ 55 | return 56 | } else{ 57 | return 58 | } 59 | 60 | 61 | } 62 | 63 | export default InputTextField; 64 | -------------------------------------------------------------------------------- /src/components/ModeSwitch/ModeSwitch.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | 3 | .modBtnContainer{ 4 | flex: 0 0 auto; 5 | display: flex; 6 | align-items: center; 7 | margin-right: 20px; 8 | 9 | span{ 10 | svg { 11 | path { 12 | fill: $eggshell; 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/components/ModeSwitch/ModeSwitch.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Light/Dark mode switch 3 | */ 4 | 5 | import React, { useContext } from 'react'; 6 | import styles from './ModeSwitch.module.scss'; 7 | import { GlobalContext } from '../../context/reducers/globalReducer'; 8 | import { toggleTheme } from '../../context/actions/globalActions'; 9 | import { BiSun, BiMoon } from 'react-icons/bi'; 10 | import { Switch } from '@mui/material'; 11 | 12 | const ModeSwitch = (): JSX.Element => { 13 | const [{ theme }, dispatchToGlobal] = useContext(GlobalContext); 14 | 15 | const changeTheme = () => { 16 | localStorage.setItem("theme", theme === 'light' ? 'dark' : 'light'); 17 | dispatchToGlobal(toggleTheme()); 18 | }; 19 | 20 | return ( 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | ); 33 | } 34 | 35 | export default ModeSwitch; -------------------------------------------------------------------------------- /src/components/NavBar/NavBar.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | #navBarlight { 5 | width: 100%; 6 | background-color: $mint; 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-between; 10 | border-radius: 5px; 11 | --icon-fill: #{$salmon}; 12 | transition: transform 0.5s ease; 13 | } 14 | 15 | #navBardark { 16 | width: 100%; 17 | background-color: $darkslategrey; 18 | display: flex; 19 | align-items: center; 20 | justify-content: space-between; 21 | border-radius: 5px; 22 | --icon-fill: #{$mint}; 23 | transition: transform 0.5s ease; 24 | 25 | } 26 | #loginBtn { 27 | color: white; 28 | } 29 | 30 | .btnContainer{ 31 | flex: 0 0 auto; 32 | margin: 10px 30px; 33 | display: flex; 34 | align-items: center; 35 | gap: 30px; 36 | 37 | span{ 38 | cursor: pointer; 39 | &:hover{ 40 | svg { 41 | path { 42 | fill: var(--icon-fill); 43 | } 44 | } 45 | } 46 | svg { 47 | path { 48 | fill: $eggshell; 49 | } 50 | } 51 | 52 | } 53 | #activeEffect { 54 | svg { 55 | path { 56 | fill: var(--icon-fill); 57 | } 58 | } 59 | } 60 | } 61 | 62 | #spearmintTitle{ 63 | flex: 1 0 auto; 64 | align-self: center; 65 | font-size: 2rem; 66 | text-align: center; 67 | font-family: 'comfortaa'; 68 | color: $eggshell; 69 | } 70 | 71 | .navBtn { 72 | padding: 0; 73 | border: 0; 74 | cursor: pointer; 75 | background-color: transparent; 76 | } 77 | 78 | .icons { 79 | width: 28px; 80 | height: 28px; 81 | } 82 | 83 | .tooltip { 84 | visibility: hidden; 85 | width: 120px; 86 | background: black; 87 | color: white; 88 | position: absolute; 89 | padding: 5px 0; 90 | text-align: center; 91 | border-radius: 8px; 92 | margin: 0 auto; 93 | z-index: 3; 94 | } 95 | 96 | .navBtn:hover .tooltip { 97 | visibility: visible; 98 | margin-left: 5px; 99 | } -------------------------------------------------------------------------------- /src/components/OpenFolder/OpenFolderButton.module.scss: -------------------------------------------------------------------------------- 1 | @import './../../assets/stylesheets/colors.scss'; 2 | 3 | .navBtn { 4 | padding: 0; 5 | border: 0; 6 | margin-top: 15px; 7 | margin-bottom: 40px; 8 | cursor: pointer; 9 | background-color: transparent; 10 | :focus { 11 | outline: 2px solid darkblue; 12 | } 13 | } 14 | 15 | .icons { 16 | width: 28px; 17 | height: 28px; 18 | } 19 | 20 | #openBtn { 21 | width: 100%; 22 | background-color: $salmon; 23 | color: $eggshell; 24 | 25 | span { 26 | width: 100%; 27 | gap: 10px; 28 | } 29 | } 30 | 31 | .tooltip { 32 | visibility: hidden; 33 | width: 120px; 34 | background: black; 35 | color: white; 36 | position: absolute; 37 | padding: 5px 0; 38 | text-align: center; 39 | border-radius: 8px; 40 | margin: 0 auto; 41 | z-index: 3; 42 | } 43 | 44 | .navBtn:hover .tooltip { 45 | visibility: visible; 46 | margin-left: 5px; 47 | } 48 | 49 | .navBtn:active .tooltip { 50 | visibility: hidden; 51 | } 52 | -------------------------------------------------------------------------------- /src/components/ReactHooksTestComponent/HooksCallback.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import styles from '../EndpointTestComponent/Endpoint.module.scss'; 3 | import { HooksTestCaseContext } from '../../context/reducers/hooksTestCaseReducer'; 4 | import { deleteCallbackFunc, updateCallbackFunc } from '../../context/actions/hooksTestCaseActions'; 5 | import { HooksCallbackProps } from '../../utils/hooksTypes'; 6 | 7 | const closeIcon = require('../../assets/images/close.png'); 8 | 9 | const HooksCallback = ({ callbackFunc, index, id }: HooksCallbackProps): JSX.Element => { 10 | const [, dispatchToHooksTestCase] = useContext(HooksTestCaseContext); 11 | 12 | const handleClickDeleteCallbackFunc = (): void => { 13 | dispatchToHooksTestCase(deleteCallbackFunc(index, id)); 14 | }; 15 | 16 | const handleChangeUpdateCallbackFunc = (e: React.ChangeEvent, field: 'callbackFunc'): void => { 17 | const updatedCallbackFunc = { ...callbackFunc, [field]: e.target.value }; 18 | dispatchToHooksTestCase(updateCallbackFunc(index, id, updatedCallbackFunc)); 19 | }; 20 | 21 | return ( 22 | <> 23 |
24 | 25 |
26 | handleChangeUpdateCallbackFunc(e, 'callbackFunc')} 32 | /> 33 |
34 |
35 | 36 | close 42 | 43 | ); 44 | }; 45 | 46 | export default HooksCallback; 47 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/Assertion/AssertionMatchers.tsx: -------------------------------------------------------------------------------- 1 | // import React, { useContext } from 'react'; 2 | // import { GlobalContext } from '../../../context/reducers/globalReducer'; 3 | // import { TextField, MenuItem } from '@mui/material'; 4 | 5 | // interface AssertionProps { 6 | // matcherType: string; 7 | // onMatcherChange: (value: string) => void; 8 | // } 9 | 10 | // const AssertionMatchers: React.FC = ({ matcherType, onMatcherChange }) => { 11 | // const [{ testFramework }] = useContext(GlobalContext); 12 | 13 | // const jestMatchers = []; 14 | 15 | // const cypressMatchers = [ 16 | // 'be.visible', 17 | // 'have.text', 18 | // 'have.length', 19 | // 'exist', 20 | // 'not.exist', 21 | // 'contain.text', 22 | // ]; 23 | 24 | // const mochaMatchers = []; 25 | 26 | // const matcherOptions = testFramework === 'cypress'? cypressMatchers 27 | // : testFramework === 'mocha'? mochaMatchers 28 | // : jestMatchers; 29 | 30 | 31 | 32 | // return ( 33 | // onMatcherChange(e.target.value)} 38 | // > 39 | // {matcherOptions.map((matcher) => ( 40 | // 41 | // {matcher} 42 | // 43 | // ))} 44 | // 45 | // ); 46 | // }; 47 | 48 | // export default AssertionMatchers; 49 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/DescribeRenderer/DescribeRenderer.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #describeBlocklight { 6 | display: flex; 7 | flex-direction: column; 8 | gap: 8px; 9 | position: relative; 10 | background-color: white; 11 | border-radius: 3px; 12 | box-shadow: 1px 1px 5px gray; 13 | display: flex; 14 | flex-direction: column; 15 | border-radius: 4px; 16 | z-index: 3; 17 | margin-bottom: 10px; 18 | button { 19 | margin: 2px; 20 | color: black; 21 | } 22 | 23 | --describe-bg: #{$lighter-mint}; 24 | --button-color: black; 25 | } 26 | 27 | #describeBlockdark { 28 | display: flex; 29 | flex-direction: column; 30 | gap: 8px; 31 | position: relative; 32 | background-color: $chromegray-less-light; 33 | border-radius: 3px; 34 | box-shadow: 1px 1px 5px gray; 35 | display: flex; 36 | flex-direction: column; 37 | border-radius: 4px; 38 | z-index: 3; 39 | margin-bottom: 10px; 40 | button { 41 | margin: 2px; 42 | color: white; 43 | } 44 | 45 | --describe-bg: #{$salmon}; 46 | --button-color: white; 47 | } 48 | 49 | .describeClose { 50 | position: absolute; 51 | top: 10px; 52 | right: 10px; 53 | font-size: 1.5rem; 54 | z-index: 20; 55 | transition: 250ms; 56 | color: white; 57 | 58 | &:hover { 59 | color: red; 60 | cursor: pointer; 61 | font-size: 1.75rem; 62 | font-weight: bold; 63 | } 64 | } 65 | 66 | .describeInputContainer { 67 | width: 100%; 68 | padding: 10px; 69 | background-color: var(--describe-bg); 70 | border-radius: 4px; 71 | 72 | input { 73 | color: white; 74 | } 75 | 76 | 77 | } 78 | 79 | .addIt { 80 | color: white; 81 | padding: 0.5rem; 82 | border-radius: 5px; 83 | background-color: $mint; 84 | // padding: 85 | 86 | 87 | &:hover { 88 | background-color: white; 89 | color: $mint; 90 | } 91 | } 92 | 93 | /*Animation for Describe block*/ 94 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/MockData/MockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #mockDatalight { 6 | @include box-styling; 7 | padding: 5px 10px 10px 8px; 8 | background-color: $light-gray2; 9 | 10 | hr { 11 | border: 1px solid $light-gray; 12 | margin-top: 0; 13 | } 14 | 15 | button:hover { 16 | color: $mint; 17 | } 18 | button { 19 | font-size: 12px; 20 | width: 30%; 21 | padding-top: 5px; 22 | border: none; 23 | font-family: $raleway; 24 | font-weight: bold; 25 | text-align: left; 26 | } 27 | 28 | input { 29 | width: 38%; 30 | } 31 | } 32 | 33 | #mockDatadark { 34 | @include box-styling; 35 | padding: 5px 10px 10px 8px; 36 | background-color: $chromegray-less-light; 37 | color: white; 38 | 39 | hr { 40 | border: 1px solid $light-gray; 41 | margin-top: 0; 42 | } 43 | 44 | button:hover { 45 | color: $mint; 46 | } 47 | button { 48 | font-size: 12px; 49 | width: 30%; 50 | padding-top: 5px; 51 | border: none; 52 | font-family: $raleway; 53 | font-weight: bold; 54 | text-align: left; 55 | } 56 | 57 | input { 58 | width: 38%; 59 | } 60 | } 61 | 62 | #close { 63 | float: right; 64 | } 65 | #mockDataHeader { 66 | padding: 10px 0; 67 | vertical-align: middle; 68 | } 69 | 70 | #keys { 71 | font-size: 13px; 72 | margin-bottom: 0; 73 | display: flex; 74 | width: 61%; 75 | justify-content: space-between; 76 | } 77 | 78 | #keyList { 79 | margin-top: 5px; 80 | } 81 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/MockData/MockDataKey.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | 3 | #mockDataKey { 4 | 5 | background-color: $light-gray2; 6 | img { 7 | width: 15px; 8 | height: 15px; 9 | cursor: pointer; 10 | } 11 | 12 | input { 13 | width: 50%; 14 | display: inline-block; 15 | margin-right: 20px; 16 | } 17 | 18 | select { 19 | width: 38%; 20 | height: 25px; 21 | margin-right: 10px; 22 | background-color: white; 23 | border: 1px solid $light-gray; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/MockData/MockDataKey.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the data for each field key and type in the card for mock data 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from './MockDataKey.module.scss'; 7 | import { deleteMockDataKey, updateMockDataKey } from '../../../context/actions/mockDataActions'; 8 | import { MockDataKeyProps } from '../../../utils/mockTypes'; 9 | 10 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 11 | 12 | const MockDataKey = ({ dispatchToMockData, mockDatumId, mockDatumKeyId, fieldKey, fieldType }: MockDataKeyProps) => { 13 | const handleChangeDelete = (e: React.MouseEvent) => { 14 | e.stopPropagation(); 15 | dispatchToMockData(deleteMockDataKey(mockDatumId, mockDatumKeyId)); 16 | }; 17 | 18 | const handleChangeUpdateFieldKey = (e: React.BaseSyntheticEvent) => { 19 | e.stopPropagation(); 20 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, e.target.value, fieldType)); 21 | }; 22 | 23 | const handleChangeUpdateFieldType = (e: React.BaseSyntheticEvent) => { 24 | e.stopPropagation(); 25 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, fieldKey, e.target.value)); 26 | }; 27 | 28 | return ( 29 |
30 |
31 | 37 | 52 | delete 53 |
54 |
55 | ); 56 | }; 57 | 58 | export default MockDataKey; 59 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/Render/Prop.module.scss: -------------------------------------------------------------------------------- 1 | @import './../../../assets/stylesheets/colors.scss'; 2 | 3 | #renderPropsFlexBoxlight { 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | color: black; 8 | 9 | input { 10 | width: 240px; 11 | margin: 0 4px 4px 0px; 12 | padding: 10px; 13 | } 14 | 15 | img { 16 | margin-bottom: 5px; 17 | } 18 | } 19 | 20 | #renderPropsFlexBoxdark { 21 | display: flex; 22 | justify-content: center; 23 | align-items: center; 24 | color: white; 25 | 26 | input { 27 | width: 240px; 28 | margin: 0 4px 4px 0px; 29 | padding: 10px; 30 | } 31 | 32 | img { 33 | margin-bottom: 5px; 34 | } 35 | } 36 | 37 | 38 | #componentName{ 39 | color: var(--component-color); 40 | } 41 | 42 | .header { 43 | font-size: 1rem; 44 | font-weight: bold; 45 | color: var(--prop-color); 46 | } 47 | .header { 48 | font-size: 1rem; 49 | font-weight: bold; 50 | color: var(--visit-color); 51 | } 52 | 53 | 54 | 55 | .close { 56 | float: right; 57 | cursor: pointer; 58 | } 59 | 60 | 61 | 62 | .description { 63 | font-size: 0.85rem; 64 | color: #666; 65 | margin-bottom: 0.75rem; 66 | } 67 | 68 | label { 69 | display: block; 70 | margin-top: 0.50rem; 71 | font-weight: 500; 72 | } 73 | 74 | input { 75 | width: 100%; 76 | padding: 0.5rem; 77 | margin-top: 0.25rem; 78 | border-radius: 4px; 79 | border: 1px solid #ccc; 80 | } 81 | 82 | // .invalid { 83 | // border-color: #e63946; 84 | // } 85 | 86 | .preview { 87 | margin-top: 1rem; 88 | font-family: monospace; 89 | background-color: #f6f8fa; 90 | padding: 0.5rem; 91 | border-radius: 4px; 92 | font-size: 0.85rem; 93 | } 94 | 95 | 96 | 97 | .urlRow { 98 | display: flex; 99 | gap: 1rem; 100 | justify-content: space-between; 101 | flex-wrap: wrap; 102 | } 103 | 104 | .urlInputGroup { 105 | flex: 1; 106 | min-width: 200px; 107 | } 108 | 109 | .urlInputGroup label { 110 | display: block; 111 | margin-bottom: 0.25rem; 112 | font-weight: 500; 113 | } 114 | 115 | .urlInputGroup input { 116 | width: 100%; 117 | padding: 0.5rem; 118 | border-radius: 4px; 119 | border: 1px solid #ccc; 120 | } 121 | -------------------------------------------------------------------------------- /src/components/ReactTestComponent/Render/Prop.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './Prop.module.scss'; 3 | import { 4 | deleteProp, 5 | updateProp, 6 | } from '../../../context/actions/frontendFrameworkTestCaseActions'; 7 | import { PropProps } from '../../../utils/reactTestCase'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | // This is the file that tracks what props you are passing into a specific test 12 | 13 | const Prop = ({ 14 | statementId, 15 | propId, 16 | propKey, 17 | propValue, 18 | dispatchToTestCase, 19 | theme, 20 | }: PropProps): JSX.Element => { 21 | const handleClickDeleteProp = (e: React.MouseEvent): void => { 22 | e.stopPropagation(); 23 | dispatchToTestCase(deleteProp(statementId, propId)); 24 | }; 25 | 26 | const handleChangeUpdatePropKey = ( 27 | e: React.ChangeEvent 28 | ): void => { 29 | e.stopPropagation(); 30 | dispatchToTestCase( 31 | updateProp(statementId, propId, e.target.value, propValue) 32 | ); 33 | }; 34 | 35 | const handleChangeUpdatePropValue = ( 36 | e: React.ChangeEvent 37 | ): void => { 38 | e.stopPropagation(); 39 | dispatchToTestCase( 40 | updateProp(statementId, propId, propKey, e.target.value) 41 | ); 42 | }; 43 | 44 | return ( 45 |
46 | {' '} 52 | 59 | {/* */} 68 | delete 69 |
70 | ); 71 | }; 72 | 73 | export default Prop; 74 | -------------------------------------------------------------------------------- /src/components/ReduxTestComponent/ActionCreator/ActionCreator.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #actionCreator { 6 | @include box-styling; 7 | font-family: $raleway; 8 | letter-spacing: 0.5px; 9 | background-color: $light-gray2; 10 | 11 | } 12 | 13 | #close { 14 | float: right; 15 | } 16 | 17 | #actionCreatorHeader { 18 | @include box-header-alignment; 19 | justify-content: flex-start; 20 | display: flex; 21 | align-items: center; 22 | 23 | img { 24 | width: 20px; 25 | height: 20px; 26 | margin: 0; 27 | padding: 0; 28 | } 29 | h3 { 30 | margin: 0; 31 | padding: 0; 32 | } 33 | } 34 | 35 | #filesFlexBox { 36 | display: flex; 37 | align-items: center; 38 | margin-bottom: 15px; 39 | } 40 | 41 | #files { 42 | width: 50%; 43 | margin-right: 7%; 44 | input { 45 | margin-top: 6px; 46 | width: 100%; 47 | } 48 | position: relative; 49 | } 50 | 51 | #actionFlexBox { 52 | display: flex; 53 | align-items: center; 54 | margin-bottom: 15px; 55 | } 56 | 57 | #actions { 58 | width: 50%; 59 | margin-right: 7%; 60 | input { 61 | margin-top: 6px; 62 | width: 100%; 63 | } 64 | } 65 | 66 | #payloadFlexBox { 67 | display: flex; 68 | align-items: center; 69 | width: 100%; 70 | } 71 | 72 | #payloadKey { 73 | width: 50%; 74 | margin-right: 7%; 75 | input { 76 | margin-top: 6px; 77 | width: 100%; 78 | } 79 | } 80 | 81 | #payloadType { 82 | margin-right: 7%; 83 | width: 50%; 84 | select { 85 | margin-top: 6px; 86 | font-family: $raleway; 87 | width: 100%; 88 | height: 25px; 89 | background-color: white; 90 | border: 1px solid $light-gray; 91 | font-size: 12px; 92 | letter-spacing: 0.5px; 93 | color: $dark-gray; 94 | } 95 | } 96 | 97 | // #dropdownFlex { 98 | // display: flex; 99 | // align-items: center; 100 | // width: 111%; 101 | // } 102 | -------------------------------------------------------------------------------- /src/components/ReduxTestComponent/Reducer/Reducer.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #reducer { 6 | @include box-styling; 7 | font-family: $raleway; 8 | letter-spacing: 0.5px; 9 | background-color: $light-gray2; 10 | } 11 | 12 | #close { 13 | float: right; 14 | margin: 0; 15 | } 16 | 17 | #reducerHeader { 18 | @include box-header-alignment; 19 | justify-content: flex-start; 20 | display: flex; 21 | align-items: center; 22 | img { 23 | width: 20px; 24 | height: 20px; 25 | margin: 0; 26 | padding: 0; 27 | } 28 | h3 { 29 | margin: 0; 30 | padding: 0; 31 | } 32 | } 33 | 34 | #reducerNameFlexBox { 35 | display: flex; 36 | align-items: center; 37 | margin-bottom: 15px; 38 | } 39 | 40 | #reducerName { 41 | width: 50%; 42 | margin-right: 7%; 43 | input { 44 | margin-top: 6px; 45 | width: 100%; 46 | } 47 | position: relative; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/components/ReduxTestComponent/Thunk/Thunk.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #modal { 6 | @include box-styling; 7 | font-family: $raleway; 8 | letter-spacing: 0.5px; 9 | background-color: $light-gray2; 10 | } 11 | 12 | #close { 13 | float: right; 14 | } 15 | 16 | #header { 17 | @include box-header-alignment; 18 | justify-content: flex-start; 19 | display: flex; 20 | align-items: center; 21 | img { 22 | width: 20px; 23 | height: 20px; 24 | margin: 0; 25 | padding: 0; 26 | } 27 | h3 { 28 | margin: 0; 29 | padding: 0; 30 | } 31 | } 32 | 33 | #groupFlexbox { 34 | display: flex; 35 | align-items: center; 36 | margin-bottom: 15px; 37 | } 38 | 39 | #labelInput { 40 | width: 50%; 41 | margin-right: 7%; 42 | input { 43 | margin-top: 6px; 44 | width: 100%; 45 | } 46 | position: relative; 47 | } 48 | 49 | #dropdownWrapper { 50 | margin-right: 9%; 51 | select { 52 | font-family: $raleway; 53 | width: 100%; 54 | height: 25px; 55 | margin: 0 3px 0 0; 56 | background-color: white; 57 | border: 1px solid $light-gray; 58 | font-size: 12px; 59 | letter-spacing: 0.5px; 60 | color: $dark-gray; 61 | } 62 | } 63 | 64 | #dropdownFlex { 65 | display: flex; 66 | align-items: center; 67 | width: 100%; 68 | margin-top: 6px; 69 | } 70 | 71 | #inputFlexBox { 72 | display: flex; 73 | align-items: center; 74 | width: 100%; 75 | } 76 | 77 | #hastooltip { 78 | @include hastooltip($tooltip-transition-in-duration: 0.3s); 79 | } 80 | 81 | #tooltip { 82 | min-width: 10em; 83 | padding: 0.5em 0.75em; 84 | 85 | box-shadow: 0 0.05em 0.15em rgba(black, 0.1); 86 | @include tooltip; 87 | } 88 | -------------------------------------------------------------------------------- /src/components/SearchInput/SearchInput.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | .search-container { 5 | position: relative; 6 | // color: white; 7 | } 8 | 9 | ul.options li:hover { 10 | font-weight: bold; 11 | color: #00b4cc; 12 | cursor: pointer; 13 | transition: 0.3s all; 14 | } 15 | 16 | ul.options li.option-active { 17 | background: whitesmoke; 18 | color: #00b4cc; 19 | } 20 | 21 | .options { 22 | background-color: white; 23 | overflow: auto; 24 | position: absolute; 25 | z-index: 1; 26 | width: -webkit-fill-available; 27 | } 28 | 29 | .react-test-options { 30 | background-color: white; 31 | overflow: auto; 32 | position: absolute; 33 | z-index: 4; 34 | width: 137px; 35 | } 36 | ul.react-test-options li:hover { 37 | font-weight: bold; 38 | color: #00b4cc; 39 | cursor: pointer; 40 | transition: 0.3s all; 41 | } 42 | 43 | ul.react-test-options li.option-active { 44 | background: whitesmoke; 45 | color: #00b4cc; 46 | } 47 | 48 | .HooksTestCaselight { 49 | gap: 10px; 50 | --input-color: black; 51 | --describe-button-color: white; 52 | --describe-button-bg: #{$mint}; 53 | } 54 | 55 | .HooksTestCasedark { 56 | gap: 10px; 57 | --input-color: white; 58 | --describe-button-color: #{$eggshell}; 59 | --describe-button-bg: #{$salmon}; 60 | } 61 | 62 | .flexContainer { 63 | // align-items: center; 64 | flex: 0 0 40px; 65 | display: flex; 66 | svg { 67 | color: var(--input-color); 68 | } 69 | div { 70 | max-width: 250px; 71 | } 72 | input { 73 | border-color: var(--input-color); 74 | color: var(--input-color); 75 | 76 | &::placeholder { 77 | color: var(--input-color); 78 | } 79 | } 80 | label { 81 | color: var(--input-color); 82 | } 83 | button { 84 | font-size: 0.75rem; 85 | color: var(--input-color); 86 | border-color: var(--input-color); 87 | } 88 | 89 | } 90 | 91 | .flex-item { 92 | width: 200px; 93 | margin-right: 7%; 94 | input { 95 | width: 100%; 96 | } 97 | position: relative; 98 | } 99 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/MockData/MockData.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the card for adding mock data 3 | * renders : 4 | * - mockDataKey (as mockDataFieldKey) 5 | * - the labels in the card (name, key, type) 6 | */ 7 | 8 | import React, { useContext } from 'react'; 9 | import styles from './MockData.module.scss'; 10 | import { 11 | deleteMockData, 12 | addMockDataKey, 13 | updateMockDataName, 14 | } from '../../../context/actions/mockDataActions'; 15 | import MockDataFieldKey from './MockDataKey'; 16 | import { GlobalContext } from '../../../context/reducers/globalReducer'; 17 | 18 | const plusIcon = require('../../../assets/images/plus.png'); 19 | const closeIcon = require('../../../assets/images/close.png'); 20 | 21 | const MockData = ({ mockDatumId, dispatchToMockData, fieldKeys }) => { 22 | 23 | const [{theme}] = useContext(GlobalContext); 24 | 25 | const handleClickAdd = (e, id) => { 26 | e.stopPropagation(); 27 | dispatchToMockData(addMockDataKey(id)); 28 | }; 29 | 30 | const handleClickDelete = (e) => { 31 | e.stopPropagation(); 32 | dispatchToMockData(deleteMockData(mockDatumId)); 33 | }; 34 | 35 | const handleClickUpdate = (e) => { 36 | e.stopPropagation(); 37 | dispatchToMockData(updateMockDataName(mockDatumId, e.target.value)); 38 | }; 39 | 40 | const mockDataFieldKeys = fieldKeys.map((key) => ( 41 | 49 | )); 50 | 51 | return ( 52 |
53 | close 54 |
55 | 56 | 57 |
58 |
59 | 62 | 65 |
66 |
67 |
68 | {mockDataFieldKeys} 69 | 73 |
74 |
75 | ); 76 | }; 77 | 78 | export default MockData; 79 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/MockData/MockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #mockDatalight { 6 | @include box-styling; 7 | padding: 5px 10px 10px 8px; 8 | background-color: $light-gray2; 9 | 10 | hr { 11 | border: 1px solid $light-gray; 12 | margin-top: 0; 13 | } 14 | 15 | button:hover { 16 | color: $mint; 17 | } 18 | button { 19 | font-size: 12px; 20 | width: 30%; 21 | padding-top: 5px; 22 | border: none; 23 | font-family: $raleway; 24 | font-weight: bold; 25 | text-align: left; 26 | } 27 | 28 | input { 29 | width: 38%; 30 | } 31 | } 32 | 33 | #mockDatadark { 34 | @include box-styling; 35 | padding: 5px 10px 10px 8px; 36 | background-color: $chromegray-less-light; 37 | color: white; 38 | 39 | hr { 40 | border: 1px solid $light-gray; 41 | margin-top: 0; 42 | } 43 | 44 | button:hover { 45 | color: $mint; 46 | } 47 | button { 48 | font-size: 12px; 49 | width: 30%; 50 | padding-top: 5px; 51 | border: none; 52 | font-family: $raleway; 53 | font-weight: bold; 54 | text-align: left; 55 | } 56 | 57 | input { 58 | width: 38%; 59 | } 60 | } 61 | 62 | #close { 63 | float: right; 64 | } 65 | #mockDataHeader { 66 | padding: 10px 0; 67 | vertical-align: middle; 68 | } 69 | 70 | #keys { 71 | font-size: 13px; 72 | margin-bottom: 0; 73 | display: flex; 74 | width: 61%; 75 | justify-content: space-between; 76 | } 77 | 78 | #keyList { 79 | margin-top: 5px; 80 | } 81 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/MockData/MockDataKey.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the data for each field key and type in the card for mock data 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from './MockDataKey.module.scss'; 7 | import { deleteMockDataKey, updateMockDataKey } from '../../../context/actions/mockDataActions'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | const MockDataKey = ({ dispatchToMockData, mockDatumId, mockDatumKeyId, fieldKey, fieldType }) => { 12 | const handleChangeDelete = (e) => { 13 | e.stopPropagation(); 14 | dispatchToMockData(deleteMockDataKey(mockDatumId, mockDatumKeyId)); 15 | }; 16 | 17 | const handleChangeUpdateFieldKey = (e) => { 18 | e.stopPropagation(); 19 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, e.target.value, fieldType)); 20 | }; 21 | 22 | const handleChangeUpdateFieldType = (e) => { 23 | e.stopPropagation(); 24 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, fieldKey, e.target.value)); 25 | }; 26 | 27 | return ( 28 |
29 |
30 | 36 | 51 | delete 52 |
53 |
54 | ); 55 | }; 56 | 57 | export default MockDataKey; 58 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/MockData/MockDataKey.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | 3 | #mockDataKey { 4 | 5 | background-color: $light-gray2; 6 | img { 7 | width: 15px; 8 | height: 15px; 9 | cursor: pointer; 10 | } 11 | 12 | input { 13 | width: 50%; 14 | display: inline-block; 15 | margin-right: 20px; 16 | } 17 | 18 | select { 19 | width: 38%; 20 | height: 25px; 21 | margin-right: 10px; 22 | background-color: white; 23 | border: 1px solid $light-gray; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/Render/Prop.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * ? 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from '../../ReactTestComponent/Render/Prop.module.scss'; 7 | import { deleteProp, updateProp } from '../../../context/actions/frontendFrameworkTestCaseActions'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | const Prop = ({ statementId, propId, propKey, propValue, dispatchToTestCase, theme }) => { 12 | const handleClickDeleteProp = (e) => { 13 | e.stopPropagation(); 14 | dispatchToTestCase(deleteProp(statementId, propId)); 15 | }; 16 | 17 | const handleChangeUpdatePropKey = (e) => { 18 | e.stopPropagation(); 19 | dispatchToTestCase(updateProp(statementId, propId, e.target.value, propValue)); 20 | }; 21 | 22 | const handleChangeUpdatePropValue = (e) => { 23 | e.stopPropagation(); 24 | dispatchToTestCase(updateProp(statementId, propId, propKey, e.target.value)); 25 | }; 26 | 27 | return ( 28 |
29 | 30 | 37 | {/* */} 46 | delete 47 |
48 | ); 49 | }; 50 | 51 | export default Prop; 52 | -------------------------------------------------------------------------------- /src/components/SolidTestComponent/Render/Render.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * functionlity to add and update props for the render 3 | */ 4 | 5 | import React, { useContext } from 'react'; 6 | import styles from '../../ReactTestComponent/Render/Render.module.scss'; 7 | import { SolidTestCaseContext } from '../../../context/reducers/solidTestCaseReducer'; 8 | 9 | import { deleteRender, addProp } from '../../../context/actions/frontendFrameworkTestCaseActions'; 10 | import Prop from './Prop'; 11 | import { Button } from '@mui/material'; 12 | import { GlobalContext } from '../../../context/reducers/globalReducer'; 13 | import { AiOutlineClose } from 'react-icons/ai'; 14 | 15 | const Render = ({ statement, statementId, describeId, itId }) => { 16 | const [{ statements }, dispatchToSolidTestCase] = useContext(SolidTestCaseContext); 17 | const [{theme}] = useContext(GlobalContext) 18 | 19 | const handleClickAddProp = () => { 20 | dispatchToSolidTestCase(addProp(statementId)); 21 | }; 22 | 23 | const handleClickDeleteRender = () => { 24 | dispatchToSolidTestCase(deleteRender(statementId)); 25 | }; 26 | 27 | return ( 28 |
29 |
30 | 31 | Rendering {statements.componentName} 32 | 33 | 36 | 37 |
38 |
39 | {statement.props.length > 0 && ( 40 |
41 |
42 | 45 | 48 |
49 |
50 | {statement.props.map((prop, i) => { 51 | return ( 52 | 61 | ); 62 | })} 63 |
64 | )} 65 |
66 |
67 | ); 68 | }; 69 | 70 | export default Render; 71 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/MockData/MockData.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the card for adding mock data 3 | * renders : 4 | * - mockDataKey (as mockDataFieldKey) 5 | * - the labels in the card (name, key, type) 6 | */ 7 | 8 | import React, { useContext } from 'react'; 9 | import styles from './MockData.module.scss'; 10 | import { 11 | deleteMockData, 12 | addMockDataKey, 13 | updateMockDataName, 14 | } from '../../../context/actions/mockDataActions'; 15 | import MockDataFieldKey from './MockDataKey'; 16 | import { GlobalContext } from '../../../context/reducers/globalReducer'; 17 | 18 | const plusIcon = require('../../../assets/images/plus.png'); 19 | const closeIcon = require('../../../assets/images/close.png'); 20 | 21 | const MockData = ({ mockDatumId, dispatchToMockData, fieldKeys }) => { 22 | 23 | const [{theme}] = useContext(GlobalContext); 24 | 25 | const handleClickAdd = (e, id) => { 26 | e.stopPropagation(); 27 | dispatchToMockData(addMockDataKey(id)); 28 | }; 29 | 30 | const handleClickDelete = (e) => { 31 | e.stopPropagation(); 32 | dispatchToMockData(deleteMockData(mockDatumId)); 33 | }; 34 | 35 | const handleClickUpdate = (e) => { 36 | e.stopPropagation(); 37 | dispatchToMockData(updateMockDataName(mockDatumId, e.target.value)); 38 | }; 39 | 40 | const mockDataFieldKeys = fieldKeys.map((key) => ( 41 | 49 | )); 50 | 51 | return ( 52 |
53 | close 54 |
55 | 56 | 57 |
58 |
59 | 62 | 65 |
66 |
67 |
68 | {mockDataFieldKeys} 69 | 73 |
74 |
75 | ); 76 | }; 77 | 78 | export default MockData; 79 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/MockData/MockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #mockDatalight { 6 | @include box-styling; 7 | padding: 5px 10px 10px 8px; 8 | background-color: $light-gray2; 9 | 10 | hr { 11 | border: 1px solid $light-gray; 12 | margin-top: 0; 13 | } 14 | 15 | button:hover { 16 | color: $mint; 17 | } 18 | button { 19 | font-size: 12px; 20 | width: 30%; 21 | padding-top: 5px; 22 | border: none; 23 | font-family: $raleway; 24 | font-weight: bold; 25 | text-align: left; 26 | } 27 | 28 | input { 29 | width: 38%; 30 | } 31 | } 32 | 33 | #mockDatadark { 34 | @include box-styling; 35 | padding: 5px 10px 10px 8px; 36 | background-color: $chromegray-less-light; 37 | color: white; 38 | 39 | hr { 40 | border: 1px solid $light-gray; 41 | margin-top: 0; 42 | } 43 | 44 | button:hover { 45 | color: $mint; 46 | } 47 | button { 48 | font-size: 12px; 49 | width: 30%; 50 | padding-top: 5px; 51 | border: none; 52 | font-family: $raleway; 53 | font-weight: bold; 54 | text-align: left; 55 | } 56 | 57 | input { 58 | width: 38%; 59 | } 60 | } 61 | 62 | #close { 63 | float: right; 64 | } 65 | #mockDataHeader { 66 | padding: 10px 0; 67 | vertical-align: middle; 68 | } 69 | 70 | #keys { 71 | font-size: 13px; 72 | margin-bottom: 0; 73 | display: flex; 74 | width: 61%; 75 | justify-content: space-between; 76 | } 77 | 78 | #keyList { 79 | margin-top: 5px; 80 | } 81 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/MockData/MockDataKey.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the data for each field key and type in the card for mock data 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from './MockDataKey.module.scss'; 7 | import { deleteMockDataKey, updateMockDataKey } from '../../../context/actions/mockDataActions'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | const MockDataKey = ({ dispatchToMockData, mockDatumId, mockDatumKeyId, fieldKey, fieldType }) => { 12 | const handleChangeDelete = (e) => { 13 | e.stopPropagation(); 14 | dispatchToMockData(deleteMockDataKey(mockDatumId, mockDatumKeyId)); 15 | }; 16 | 17 | const handleChangeUpdateFieldKey = (e) => { 18 | e.stopPropagation(); 19 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, e.target.value, fieldType)); 20 | }; 21 | 22 | const handleChangeUpdateFieldType = (e) => { 23 | e.stopPropagation(); 24 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, fieldKey, e.target.value)); 25 | }; 26 | 27 | return ( 28 |
29 |
30 | 36 | 51 | delete 52 |
53 |
54 | ); 55 | }; 56 | 57 | export default MockDataKey; 58 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/MockData/MockDataKey.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | 3 | #mockDataKey { 4 | 5 | background-color: $light-gray2; 6 | img { 7 | width: 15px; 8 | height: 15px; 9 | cursor: pointer; 10 | } 11 | 12 | input { 13 | width: 50%; 14 | display: inline-block; 15 | margin-right: 20px; 16 | } 17 | 18 | select { 19 | width: 38%; 20 | height: 25px; 21 | margin-right: 10px; 22 | background-color: white; 23 | border: 1px solid $light-gray; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/Render/Prop.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * ? 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from '../../ReactTestComponent/Render/Prop.module.scss'; 7 | import { deleteProp, updateProp } from '../../../context/actions/frontendFrameworkTestCaseActions'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | const Prop = ({ statementId, propId, propKey, propValue, dispatchToTestCase, theme }) => { 12 | const handleClickDeleteProp = (e) => { 13 | e.stopPropagation(); 14 | dispatchToTestCase(deleteProp(statementId, propId)); 15 | }; 16 | 17 | const handleChangeUpdatePropKey = (e) => { 18 | e.stopPropagation(); 19 | dispatchToTestCase(updateProp(statementId, propId, e.target.value, propValue)); 20 | }; 21 | 22 | const handleChangeUpdatePropValue = (e) => { 23 | e.stopPropagation(); 24 | dispatchToTestCase(updateProp(statementId, propId, propKey, e.target.value)); 25 | }; 26 | 27 | return ( 28 |
29 | 30 | 37 | {/* */} 46 | delete 47 |
48 | ); 49 | }; 50 | 51 | export default Prop; 52 | -------------------------------------------------------------------------------- /src/components/SvelteTestComponent/Render/Render.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * functionlity to add and update props for the render 3 | */ 4 | 5 | import React, { useContext } from 'react'; 6 | import styles from '../../ReactTestComponent/Render/Render.module.scss'; 7 | import { SvelteTestCaseContext } from '../../../context/reducers/svelteTestCaseReducer'; 8 | 9 | import { deleteRender, addProp } from '../../../context/actions/frontendFrameworkTestCaseActions'; 10 | import Prop from './Prop'; 11 | import { Button } from '@mui/material'; 12 | import { GlobalContext } from '../../../context/reducers/globalReducer'; 13 | import { AiOutlineClose } from 'react-icons/ai'; 14 | 15 | const Render = ({ statement, statementId, describeId, itId }) => { 16 | const [{ statements }, dispatchToSvelteTestCase] = useContext(SvelteTestCaseContext); 17 | const [{theme}] = useContext(GlobalContext) 18 | 19 | const handleClickAddProp = () => { 20 | dispatchToSvelteTestCase(addProp(statementId)); 21 | }; 22 | 23 | const handleClickDeleteRender = () => { 24 | dispatchToSvelteTestCase(deleteRender(statementId)); 25 | }; 26 | 27 | return ( 28 |
29 |
30 | 31 | Rendering {statements.componentName} 32 | 33 | 36 | 37 |
38 |
39 | {statement.props.length > 0 && ( 40 |
41 |
42 | 45 | 48 |
49 |
50 | {statement.props.map((prop, i) => { 51 | return ( 52 | 61 | ); 62 | })} 63 |
64 | )} 65 |
66 |
67 | ); 68 | }; 69 | 70 | export default Render; 71 | -------------------------------------------------------------------------------- /src/components/Terminal/Terminal.css: -------------------------------------------------------------------------------- 1 | #terminalContainer{ 2 | width: 100%; 3 | height: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/Terminal/TerminalView.tsx: -------------------------------------------------------------------------------- 1 | import React, { useLayoutEffect } from 'react'; 2 | import { Terminal } from "xterm"; 3 | import { FitAddon } from "xterm-addon-fit"; 4 | import "./xterm.css"; 5 | import "./Terminal.css"; 6 | import { ipcRenderer } from 'electron'; 7 | const ipc = require('electron').ipcRenderer; 8 | 9 | const terminalArgs = { 10 | convertEol: true, 11 | fontSize: 12, 12 | // Currently rows are hardcoded, next step is to make terminal sizing dynamic. 13 | fontFamily: 'monospace', 14 | //rendererType: "dom", 15 | rows: 60, 16 | cols: 100, 17 | }; 18 | 19 | const term = new Terminal(terminalArgs); 20 | const fitAddon = new FitAddon(); 21 | term.loadAddon(fitAddon); 22 | 23 | /** 24 | * React component that renders on the RightPanel component 25 | * @returns { JSX.Element } returns the TerminalView component 26 | */ 27 | const TerminalView = (): JSX.Element => { 28 | useLayoutEffect(() => { 29 | const terminalContainer = document.getElementById('terminalContainer') as HTMLElement 30 | term.open(terminalContainer); 31 | // when we have input events (e), we would send the data to the main processor 32 | const onData = term.onData((e) => { 33 | ipc.send('terminal.toTerm', e); 34 | }); 35 | // when incoming Data comes back to the main process, this ipc renderer 36 | // will take it and writes it to xterm monitor 37 | ipc.on('terminal.incData', (event, data) => { 38 | term.write(data); 39 | }); 40 | 41 | fitAddon.fit(); 42 | 43 | // remove event listeners when component is unmounted 44 | return () => { 45 | ipcRenderer.removeAllListeners('terminal.incData'); 46 | onData.dispose(); 47 | } 48 | }, []); 49 | 50 | useLayoutEffect(() => { 51 | fitAddon.fit(); 52 | 53 | // tell ptyprocess to resize also 54 | term.onResize((e) => { 55 | ipc.send('terminal.resize', e, term.cols, term.rows); 56 | }) 57 | }); 58 | 59 | return ( 60 |
61 |
62 | ) 63 | }; 64 | 65 | export default TerminalView; 66 | -------------------------------------------------------------------------------- /src/components/TestCase/EndpointTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import Endpoint from '../EndpointTestComponent/Endpoint'; 3 | import { EndpointTestCaseContext } from '../../context/reducers/endpointTestCaseReducer'; 4 | import { EndpointObj } from '../../utils/endpointTypes'; 5 | 6 | const EndpointTestStatements = () => { 7 | const [{ endpointStatements }, dispatch] = useContext(EndpointTestCaseContext); 8 | 9 | return ( 10 | <> 11 | {endpointStatements.map((statement: EndpointObj, i: number) => { 12 | switch (statement.type) { 13 | /* add statements here. Ex: */ 14 | case 'endpoint': 15 | return ( 16 | 22 | ); 23 | default: 24 | return <>; 25 | } 26 | })} 27 | 28 | ); 29 | }; 30 | 31 | export default EndpointTestStatements; 32 | -------------------------------------------------------------------------------- /src/components/TestCase/GraphQLTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import GraphQL from '../GraphQLTestComponent/GraphQL'; 3 | import { GraphQLTestCaseContext } from '../../context/reducers/graphQLTestCaseReducer'; 4 | import { GraphQLObj } from '../../utils/graphQLTypes'; 5 | 6 | const GraphQLTestStatements = () => { 7 | const [{ graphQLStatements }, dispatch] = useContext(GraphQLTestCaseContext); 8 | 9 | return ( 10 | <> 11 | {graphQLStatements.map((statement: GraphQLObj, i: number) => { 12 | switch (statement.type) { 13 | /* add statements here. Ex: */ 14 | case 'graphQL': 15 | return ( 16 | 22 | ); 23 | default: 24 | return <>; 25 | } 26 | })} 27 | 28 | ); 29 | }; 30 | 31 | export default GraphQLTestStatements; 32 | -------------------------------------------------------------------------------- /src/components/TestCase/HooksTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import HookUpdates from '../ReactHooksTestComponent/HookUpdates/HookUpdates'; 3 | import { HooksTestCaseContext } from '../../context/reducers/hooksTestCaseReducer'; 4 | import { Hooks } from '../../utils/hooksTypes'; 5 | import importOptionsSwitch from './importOptions'; 6 | import SearchInput from '../SearchInput/SearchInput'; 7 | import { updateHooksFilePath } from '../../context/actions/hooksTestCaseActions'; 8 | import styles from '../../components/TestCase/TestCase.module.scss'; 9 | import { GlobalContext } from '../../context/reducers/globalReducer'; 10 | 11 | 12 | const HooksTestStatements = (): JSX.Element => { 13 | // hooksStatements is an array of objects of interface Hooks from hooksTestCaseState 14 | const [{ hooksStatements }, dispatchToHooksTestCase] = useContext(HooksTestCaseContext); 15 | const { isHooksOn } = importOptionsSwitch(hooksStatements); 16 | const [{ filePathMap, theme }] = useContext(GlobalContext); 17 | 18 | let hImports = null; 19 | if (isHooksOn) { 20 | hImports = ( 21 |
22 | 29 |
30 | ); 31 | } 32 | return ( 33 | <> 34 | {hImports} 35 | {hooksStatements.map((statement: Hooks, i: number) => { 36 | switch (statement.type) { 37 | case 'hooks': 38 | return ; 39 | default: 40 | return <>; 41 | } 42 | })} 43 | 44 | ); 45 | }; 46 | 47 | export default HooksTestStatements; 48 | -------------------------------------------------------------------------------- /src/components/TestCase/PuppeteerTestCase.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useRef, useEffect } from 'react'; 2 | import { PuppeteerTestCaseContext } from '../../context/reducers/puppeteerTestCaseReducer'; 3 | import PuppeteerTestMenu from '../TestMenu/PuppeteerTestMenu'; 4 | import PuppeteerTestStatements from './PuppeteerTestStatements'; 5 | import { 6 | addPuppeteerPaintTiming, 7 | updateStatementsOrder, 8 | } from '../../context/actions/puppeteerTestCaseActions'; 9 | import { PuppeteerStatements } from '../../utils/puppeteerTypes'; 10 | 11 | //additions fo previously ExportFileModal functionality 12 | import styles from './TestCase.module.scss'; 13 | import { Button } from '@mui/material'; 14 | import { GlobalContext } from '../../context/reducers/globalReducer'; 15 | 16 | const PuppeteerTestCase = () => { 17 | const handleAddPuppeteerPaintTiming = () => { 18 | dispatchToPuppeteerTestCase(addPuppeteerPaintTiming()); 19 | }; 20 | 21 | const [{ puppeteerStatements }, dispatchToPuppeteerTestCase] = useContext( 22 | PuppeteerTestCaseContext 23 | ); 24 | 25 | const [{ theme }] = useContext(GlobalContext); 26 | const testDescription = useRef(null); 27 | 28 | useEffect(() => { 29 | if (testDescription && testDescription.current) { 30 | testDescription.current.focus(); 31 | } 32 | }, []); 33 | 34 | const reorder = ( 35 | list: Array, 36 | startIndex: number, 37 | endIndex: number 38 | ) => { 39 | const result = Array.from(list); 40 | const [removed] = result.splice(startIndex, 1); 41 | result.splice(endIndex, 0, removed); 42 | return result; 43 | }; 44 | 45 | return ( 46 |
47 | 51 |
52 | 53 |
54 | 63 |
64 |
65 | ); 66 | }; 67 | 68 | export default PuppeteerTestCase; 69 | -------------------------------------------------------------------------------- /src/components/TestCase/PuppeteerTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import PaintTiming from '../PuppeteerTestComponent/PaintTiming/PaintTiming'; 3 | import { PuppeteerTestCaseContext } from '../../context/reducers/puppeteerTestCaseReducer'; 4 | import { PuppeteerStatements } from '../../utils/puppeteerTypes'; 5 | 6 | const PuppeteerTestStatements = () => { 7 | const [{ puppeteerStatements }] = useContext(PuppeteerTestCaseContext); 8 | 9 | return ( 10 | <> 11 | {puppeteerStatements.map((statement: PuppeteerStatements, i: number) => { 12 | switch (statement.type) { 13 | case 'paintTiming': 14 | return ; 15 | default: 16 | return <>; 17 | } 18 | })} 19 | 20 | ); 21 | }; 22 | 23 | export default PuppeteerTestStatements; 24 | -------------------------------------------------------------------------------- /src/components/TestCase/ReactContainer.module.scss: -------------------------------------------------------------------------------- 1 | @import '/../../assets/stylesheets/colors.scss'; 2 | 3 | 4 | #ReactContainer { 5 | .describeBlockContainer { 6 | background-color: white; 7 | box-sizing: border-box; 8 | width: 100%; 9 | padding: 1rem; 10 | margin-top: 1rem; 11 | box-shadow: 0 0.05em 0.15em rgba(black, 0.1); 12 | 13 | .describe { 14 | font-size: 1.25rem; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/components/TestCase/ReactTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Action from '../ReactTestComponent/Action/Action'; 3 | import Assertion from '../ReactTestComponent/Assertion/Assertion'; 4 | import Render from '../ReactTestComponent/Render/Render'; 5 | import { Statements } from '../../utils/reactTestCase'; 6 | 7 | interface ReactTestStatementsProps { 8 | statements: Statements; 9 | itId: string; 10 | describeId: string; 11 | } 12 | 13 | const ReactTestStatements = ({ 14 | statements, 15 | itId, 16 | describeId, 17 | }: ReactTestStatementsProps) => { 18 | // filter out ids not belonging to the correct describe block and itStatement 19 | const filterStatements = statements.allIds.filter((id) => { 20 | return ( 21 | statements.byId[id].describeId === describeId && 22 | statements.byId[id].itId === itId 23 | ); 24 | }); 25 | 26 | return ( 27 | <> 28 | {filterStatements.map((id, i) => { 29 | switch (statements.byId[id].type) { 30 | case 'action': 31 | return ( 32 | 39 | ); 40 | case 'assertion': 41 | return ( 42 | 49 | ); 50 | case 'render': 51 | return ( 52 | 59 | ); 60 | default: 61 | return <>; 62 | } 63 | })} 64 | 65 | ); 66 | }; 67 | 68 | export default ReactTestStatements; 69 | -------------------------------------------------------------------------------- /src/components/TestCase/SolidTestStatements.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Action from '../SolidTestComponent/Action/Action'; 3 | import Assertion from '../SolidTestComponent/Assertion/Assertion'; 4 | import Render from '../SolidTestComponent/Render/Render'; 5 | 6 | const SolidTestStatements = ({ statements, itId, describeId }) => { 7 | 8 | // filter out ids not belonging to the correct describe block and itStatement 9 | const filterStatements = statements.allIds.filter((id) => { 10 | return statements.byId[id].describeId === describeId && statements.byId[id].itId === itId; 11 | }); 12 | 13 | return filterStatements.map((id, i) => { 14 | switch (statements.byId[id].type) { 15 | case 'action': 16 | return ( 17 | 24 | ); 25 | case 'assertion': 26 | return ( 27 | 34 | ); 35 | case 'render': 36 | return ( 37 | 44 | ); 45 | default: 46 | return <>; 47 | } 48 | }); 49 | }; 50 | 51 | 52 | export default SolidTestStatements; -------------------------------------------------------------------------------- /src/components/TestCase/SvelteTestStatements.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Action from '../SvelteTestComponent/Action/Action'; 3 | import Assertion from '../SvelteTestComponent/Assertion/Assertion'; 4 | import Render from '../SvelteTestComponent/Render/Render'; 5 | 6 | const SvelteTestStatements = ({ statements, itId, describeId }) => { 7 | 8 | // filter out ids not belonging to the correct describe block and itStatement 9 | const filterStatements = statements.allIds.filter((id) => { 10 | return statements.byId[id].describeId === describeId && statements.byId[id].itId === itId; 11 | }); 12 | 13 | return filterStatements.map((id, i) => { 14 | switch (statements.byId[id].type) { 15 | case 'action': 16 | return ( 17 | 24 | ); 25 | case 'assertion': 26 | return ( 27 | 34 | ); 35 | case 'render': 36 | return ( 37 | 44 | ); 45 | default: 46 | return <>; 47 | } 48 | }); 49 | }; 50 | 51 | 52 | export default SvelteTestStatements; -------------------------------------------------------------------------------- /src/components/TestCase/TestFrameworkToggle.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { GlobalContext } from '../../context/reducers/globalReducer'; 3 | import { actionTypes } from '../../context/actions/globalActions'; 4 | import { FormControl, InputLabel, Select, MenuItem } from '@mui/material'; 5 | 6 | const TestFrameworkToggle = () => { 7 | const [globalState, dispatchToGlobal] = useContext(GlobalContext); 8 | const { testFramework } = globalState; 9 | 10 | const handleChange = (event) => { 11 | dispatchToGlobal({ 12 | type: actionTypes.SET_TEST_FRAMEWORK, 13 | testFramework: event.target.value, 14 | }); 15 | }; 16 | 17 | return ( 18 | 19 | Test Framework 20 | 32 | 33 | ); 34 | }; 35 | 36 | export default TestFrameworkToggle; -------------------------------------------------------------------------------- /src/components/TestCase/UpdatedReactTestStatements.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Action from '../UpdatedReactTestComponent/Action/Action'; 3 | import Assertion from '../UpdatedReactTestComponent/Assertion/Assertion'; 4 | import Render from '../UpdatedReactTestComponent/Render/NOT_USED_Render'; 5 | import { Statements } from '../../utils/reactTestCase'; 6 | 7 | interface ReactTestStatementsProps { 8 | statements: Statements; 9 | itId: string; 10 | describeId: string; 11 | } 12 | 13 | const ReactTestStatements = ({ 14 | statements, 15 | itId, 16 | describeId, 17 | }: ReactTestStatementsProps) => { 18 | // filter out ids not belonging to the correct describe block and itStatement 19 | const filterStatements = statements.allIds.filter((id) => { 20 | return ( 21 | statements.byId[id].describeId === describeId && 22 | statements.byId[id].itId === itId 23 | ); 24 | }); 25 | 26 | return ( 27 | <> 28 | {filterStatements.map((id, i) => { 29 | switch (statements.byId[id].type) { 30 | case 'action': 31 | return ( 32 | 39 | ); 40 | case 'assertion': 41 | return ( 42 | 49 | ); 50 | case 'render': 51 | case 'visit': 52 | return ( 53 | 60 | ); 61 | default: 62 | return <>; 63 | } 64 | })} 65 | 66 | ); 67 | }; 68 | 69 | export default ReactTestStatements; 70 | -------------------------------------------------------------------------------- /src/components/TestCase/VueTestStatements.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Action from '../VueTestComponent/Action/Action'; 3 | import Assertion from '../VueTestComponent/Assertion/Assertion'; 4 | import Render from '../VueTestComponent/Render/Render'; 5 | 6 | const VueTestStatements = ({ statements, itId, describeId }) => { 7 | // filter out ids not belonging to the correct describe block and itStatement 8 | const filterStatements = statements.allIds.filter((id) => { 9 | return statements.byId[id].describeId === describeId && statements.byId[id].itId === itId; 10 | }); 11 | 12 | return filterStatements.map((id, i) => { 13 | switch (statements.byId[id].type) { 14 | case 'action': 15 | return ( 16 | 23 | ); 24 | case 'assertion': 25 | return ( 26 | 33 | ); 34 | case 'render': 35 | return ( 36 | 43 | ); 44 | default: 45 | return <>; 46 | } 47 | }); 48 | }; 49 | 50 | export default VueTestStatements; 51 | -------------------------------------------------------------------------------- /src/components/TestCase/importOptions.ts: -------------------------------------------------------------------------------- 1 | interface statements { 2 | type: string; 3 | } 4 | 5 | export default function importOptionsSwitch(statements: statements[]) { 6 | let isReducerOn = false; 7 | let isMiddleWareOn = false; 8 | let isActionCreatorOn = false; 9 | let isAsyncOn = false; 10 | let isHooksOn = false; 11 | 12 | statements.forEach(({ type }) => { 13 | switch (type) { 14 | case 'reducer': 15 | isReducerOn = true; 16 | break; 17 | case 'middleware': 18 | isMiddleWareOn = true; 19 | break; 20 | case 'action-creator': 21 | isActionCreatorOn = true; 22 | break; 23 | case 'async': 24 | isAsyncOn = true; 25 | break; 26 | case 'hooks': 27 | isHooksOn = true; 28 | break; 29 | default: 30 | break; 31 | } 32 | }); 33 | return { 34 | isReducerOn, 35 | isMiddleWareOn, 36 | isActionCreatorOn, 37 | isAsyncOn, 38 | isHooksOn, 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/components/TestMenu/TestMenu.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | /** 4 | * ---------------------------------------- 5 | * animation slide-in-elliptic-top-fwd 6 | * ---------------------------------------- 7 | */ 8 | #testMenulight { 9 | 10 | * { 11 | transition: color 0.0s !important; 12 | } 13 | 14 | flex: 0 0 42px; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | gap: 16px; 19 | width: 100%; 20 | 21 | button { 22 | color: $mint; 23 | height: 100%; 24 | 25 | &:hover { 26 | color: white; 27 | background-color: $chromegray-opaque; 28 | } 29 | 30 | svg { 31 | font-size: 32px; 32 | } 33 | } 34 | 35 | } 36 | 37 | #testMenudark { 38 | 39 | * { 40 | transition: color 0.0s !important; 41 | } 42 | 43 | flex: 0 0 48px; 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | gap: 16px; 48 | width: 100%; 49 | 50 | button { 51 | color: $eggshell; 52 | height: 100%; 53 | 54 | &:hover { 55 | color: white; 56 | background-color: $eggshell-opaque; 57 | } 58 | 59 | svg { 60 | font-size: 32px; 61 | } 62 | } 63 | 64 | } 65 | 66 | #dbConfiglight { 67 | flex: 0 0 48px; 68 | display: flex; 69 | justify-content: center; 70 | align-items: center; 71 | gap: 16px; 72 | width: 100%; 73 | button { 74 | color: $mint; 75 | 76 | &:hover { 77 | color: white; 78 | background-color: $chromegray-opaque; 79 | } 80 | } 81 | } 82 | 83 | #dbConfigdark { 84 | flex: 0 0 48px; 85 | display: flex; 86 | justify-content: center; 87 | align-items: center; 88 | gap: 16px; 89 | width: 100%; 90 | button { 91 | color: $eggshell; 92 | background-color: $salmon; 93 | 94 | &:hover { 95 | color: white; 96 | background-color: $salmon-darker; 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /src/components/TestMenu/TestMenuButtons.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import styles from '../TestMenu/TestMenu.module.scss'; 3 | import { IconButton } from '@mui/material'; 4 | import VisibilityIcon from '@mui/icons-material/Visibility'; 5 | import PlayArrowIcon from '@mui/icons-material/PlayArrow'; 6 | import HelpIcon from '@mui/icons-material/Help'; 7 | import SaveIcon from '@mui/icons-material/Save'; 8 | import CachedIcon from '@mui/icons-material/Cached'; 9 | import { GlobalContext } from '../../context/reducers/globalReducer'; 10 | 11 | const TestMenuButtons = ({ 12 | resetTests, 13 | fileHandle, 14 | openScriptModal, 15 | saveTest, 16 | openDocs 17 | }) => { 18 | 19 | const [{ theme }] = useContext(GlobalContext); 20 | 21 | return ( 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | ); 44 | }; 45 | 46 | export default TestMenuButtons; -------------------------------------------------------------------------------- /src/components/TestMenu/testMenuHooks.js: -------------------------------------------------------------------------------- 1 | import { useState, useContext } from 'react'; 2 | import { GlobalContext } from '../../context/reducers/globalReducer'; 3 | import { setTabIndex } from '../../context/actions/globalActions'; 4 | 5 | export function useToggleModal(test) { 6 | const [isModalOpen, setIsModalOpen] = useState(false); 7 | const [title, setTitle] = useState(test); 8 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 9 | const [{ isFileDirectoryOpen }, dispatchToGlobal] = useContext(GlobalContext); 10 | 11 | const openModal = () => { 12 | setTitle(test); 13 | setIsModalOpen(true); 14 | }; 15 | 16 | const openScriptModal = () => { 17 | setTitle(title); 18 | setIsModalOpen(true); 19 | dispatchToGlobal(setTabIndex(2)); 20 | }; 21 | 22 | const closeModal = () => { 23 | setIsModalOpen(false); 24 | setTitle(test); 25 | }; 26 | 27 | return { 28 | title, isModalOpen, openModal, openScriptModal, closeModal, setIsModalOpen 29 | }; 30 | } 31 | 32 | export const validateInputs = (testSuite, testCaseState) => { 33 | let endpoint, assertion; 34 | const { serverFilePath, addDB, dbFilePath, endpointStatements } = testCaseState; 35 | switch (testSuite) { 36 | case 'endpoint': 37 | if (!serverFilePath || (addDB && !dbFilePath)) return false; 38 | for (endpoint of endpointStatements) { 39 | if (!endpoint.method || !endpoint.route) return false; 40 | for (assertion of endpoint.assertions) { 41 | if (!assertion.expectedResponse || !assertion.value || !assertion.matcher) return false; 42 | } 43 | } 44 | return true; 45 | case 'hooks': 46 | let hookTest, callback; 47 | for (hookTest of testCaseState) { 48 | if (!hookTest.hookFilePath || !hookTest.hook) return false; 49 | for (callback of hookTest.callbackFunc) { 50 | if (!callback.callbackFunc) { 51 | return false; 52 | } 53 | } 54 | for (assertion of hookTest.assertions) { 55 | if (!assertion.expectedState || !assertion.expectedValue || !assertion.matcher) 56 | return false; 57 | } 58 | } 59 | return true; 60 | default: 61 | return true; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /src/components/TestMenu/updatedCypressReactComponent.tsx/Statement/CypressTestStatments.tsx: -------------------------------------------------------------------------------- 1 | // import React from 'react'; 2 | // import { CypressReactTestCaseTypes } from '../../../../../utils/cypressReactTypes'; 3 | // import Action from './Action'; // todo 4 | // import Assertion from './Assertion'; // todo 5 | // import Render from './Render'; // todo 6 | 7 | // interface Props { 8 | // statements: CypressReactTestCaseTypes['statements']; 9 | // itId: string; 10 | // describeId: string; 11 | // } 12 | 13 | // const CypressTestStatements: React.FC = ({ statements, itId, describeId }) => { 14 | // const filteredStatements = statements.allIds.filter( 15 | // (id) => 16 | // statements.byId[id].itId === itId && 17 | // statements.byId[id].describeId === describeId 18 | // ); 19 | 20 | // return ( 21 | // <> 22 | // {filteredStatements.map((id, i) => { 23 | // const statement = statements.byId[id]; 24 | // switch (statement.type) { 25 | // case 'action': 26 | // return ( 27 | // 34 | // ); 35 | // case 'assertion': 36 | // return ( 37 | // 44 | // ); 45 | // case 'render': 46 | // return ( 47 | // 54 | // ); 55 | // default: 56 | // return null; 57 | // } 58 | // })} 59 | // 60 | // ); 61 | // }; 62 | 63 | // export default CypressTestStatements; 64 | -------------------------------------------------------------------------------- /src/components/ToolTip/ToolTip.scss: -------------------------------------------------------------------------------- 1 | @import '../../pages/LeftPanel/LeftPanel.module.scss'; 2 | 3 | #hastooltip { 4 | @include hastooltip($tooltip-transition-in-duration: 0.3s); 5 | } 6 | 7 | #tooltip { 8 | min-width: 10em; 9 | padding: 0.5em 0.75em; 10 | @include tooltip; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/ToolTip/ToolTipAsync.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Currently this is not being imported in other components. IT IS NOT IN USE. 3 | * This component provides additional notes for each Assertion matcher when you hover over the ? mark. 4 | * The object containing all tooltip matchers can be found in the utils folder under toolTipTypes. 5 | */ 6 | 7 | import React from 'react'; 8 | import { AsyncProps, ToolTipAsyncType, TOOLTIP_MAP_ASYNC } from '../../utils/toolTipTypes'; 9 | 10 | const ToolTipAsync = ({ toolTipType }: AsyncProps) => { 11 | if (toolTipType.includes('.')) { 12 | toolTipType = toolTipType.replace(/\./g, '') as ToolTipAsyncType; 13 | } 14 | 15 | return {TOOLTIP_MAP_ASYNC[toolTipType]}; 16 | }; 17 | 18 | export default ToolTipAsync; 19 | -------------------------------------------------------------------------------- /src/components/ToolTip/ToolTipMatcher.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * This component provides the notes for each Assertion matcher when you hover over the ? mark. 3 | * The object containing all tooltip matchers can be found in the utils folder under toolTipTypes. 4 | */ 5 | 6 | import React from 'react'; 7 | import { MatchersProps, TOOLTIP_MAP_MATCHERS, ToolTipMatcherType } from '../../utils/toolTipTypes'; 8 | 9 | const ToolTipMatcher = ({ toolTipType }: MatchersProps) => { 10 | if (toolTipType.includes('.')) { 11 | toolTipType = toolTipType.replace(/\./g, '') as ToolTipMatcherType; 12 | } 13 | 14 | return {TOOLTIP_MAP_MATCHERS[toolTipType]}; 15 | }; 16 | 17 | export default ToolTipMatcher; -------------------------------------------------------------------------------- /src/components/TypesList/cypressMatcherTypeList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of event types that are used in the AutoComplete component to help with the auto complete process 3 | * This list is imported in the AutoComplete functionality for assertion matcher autocomplete. 4 | */ 5 | interface MatcherType { 6 | name: string 7 | } 8 | 9 | // components/TypesList/cypressMatcherTypesList.ts 10 | 11 | export interface MatcherType { 12 | name: string; 13 | description?: string; 14 | } 15 | 16 | export const cypressMatcherTypesList: Array = [ 17 | { name: 'should.have.text', description: 'Checks element has exact text' }, 18 | { name: 'should.have.value', description: 'Checks input has value' }, 19 | { name: 'should.contain', description: 'Checks element contains text' }, 20 | { name: 'should.have.attr', description: 'Checks attribute exists or has value' }, 21 | { name: 'should.have.class', description: 'Checks class name exists on element' }, 22 | { name: 'should.have.css', description: 'Checks element has CSS property' }, 23 | { name: 'should.have.length', description: 'Checks number of matched elements' }, 24 | { name: 'should.include', description: 'Checks value is included in set' }, 25 | { name: 'should.eq', description: 'Checks values are strictly equal' }, 26 | { name: 'should.be.disabled', description: 'Checks element is disabled' }, 27 | { name: 'should.be.visible', description: 'Checks element is visible' }, 28 | { name: 'should.not.be.visible', description: 'Checks element is hidden' }, 29 | { name: 'should.not.exist', description: 'Checks element does not exist' }, 30 | { name: 'should.not.have.value', description: 'Checks input does not have value' }, 31 | ]; 32 | -------------------------------------------------------------------------------- /src/components/TypesList/cypressQueryActionTypesList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of event types that are used in the AutoComplete component to help with the auto complete process 3 | * TODO: The functionality for autocompleting eventtypes is not currently in use. Check AutoComplete Component. 4 | */ 5 | interface EventType { 6 | name: string 7 | description: string 8 | } 9 | 10 | export const cypressQueryActionTypesList: Array = [ 11 | 12 | { name: 'click', description: '.' }, 13 | { name: 'dblclick', description: '.' }, 14 | { name: 'rightclick', description: '.' }, 15 | { name: 'type', description: '.' }, 16 | { name: 'clear', description: '.' }, 17 | { name: 'check', description: '.' }, 18 | { name: 'uncheck', description: '.' }, 19 | { name: 'select', description: '.' }, 20 | { name: 'trigger', description: '.' }, 21 | { name: 'selectFile', description: '.' }, 22 | ]; 23 | 24 | export const cypressSelectorTypesList: Array = [ 25 | 26 | { name: 'get', description: 'A selector used to filter matching CSS DOM elements.' }, 27 | { name: 'contains', description: 'To find this element by its contents.' }, 28 | { name: 'find', description: 'A selector used to filter matching DOM elements.' }, 29 | { name: 'filter', description: 'narrow down results from previous query.' }, 30 | { name: 'eq', description: 'select element at a specific index.' }, 31 | { name: 'first', description: 'get the first element from matched set.' }, 32 | { name: 'last', description: 'get the last element from matched set.' }, 33 | { name: 'parent', description: 'navigate DOM hierarchy.' }, 34 | { name: 'children', description: 'navigate DOM hierarchy.' }, 35 | { name: 'closest', description: 'navigate DOM hierarchy.' }, 36 | { name: 'within', description: 'scope DOM commands to a portion of the page.' }, 37 | ]; 38 | // add later 39 | /* 40 | { name: 'eq', description: 'select element at a specific index.' }, 41 | { name: 'first', description: 'get the first element from matched set.' }, 42 | { name: 'last', description: 'get the last element from matched set.' }, 43 | { name: 'parent', description: 'navigate DOM hierarchy.' }, 44 | { name: 'children', description: 'navigate DOM hierarchy.' }, 45 | { name: 'closest', description: 'navigate DOM hierarchy.' }, 46 | { name: 'within', description: 'scope DOM commands to a portion of the page.' }, 47 | */ 48 | -------------------------------------------------------------------------------- /src/components/TypesList/cypressQuerySelectorTypesList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of event types that are used in the AutoComplete component to help with the auto complete process 3 | * TODO: The functionality for autocompleting eventtypes is not currently in use. Check AutoComplete Component. 4 | */ 5 | interface EventType { 6 | name: string 7 | } 8 | 9 | export const cypressSelectorTypesList: Array = [ 10 | 11 | { name: 'get', description: 'A selector used to filter matching CSS DOM elements.' }, 12 | { name: 'contains', description: 'To find this element by its contents.' }, 13 | { name: 'find', description: 'A selector used to filter matching DOM elements.' }, 14 | { name: 'filter', description: 'narrow down results from previous query.' }, 15 | { name: 'eq', description: 'select element at a specific index.' }, 16 | { name: 'first', description: 'get the first element from matched set.' }, 17 | { name: 'last', description: 'get the last element from matched set.' }, 18 | { name: 'parent', description: 'navigate DOM hierarchy.' }, 19 | { name: 'children', description: 'navigate DOM hierarchy.' }, 20 | { name: 'closest', description: 'navigate DOM hierarchy.' }, 21 | { name: 'within', description: 'scope DOM commands to a portion of the page.' }, 22 | ]; 23 | // add later 24 | /* 25 | { name: 'eq', description: 'select element at a specific index.' }, 26 | { name: 'first', description: 'get the first element from matched set.' }, 27 | { name: 'last', description: 'get the last element from matched set.' }, 28 | { name: 'parent', description: 'navigate DOM hierarchy.' }, 29 | { name: 'children', description: 'navigate DOM hierarchy.' }, 30 | { name: 'closest', description: 'navigate DOM hierarchy.' }, 31 | { name: 'within', description: 'scope DOM commands to a portion of the page.' }, 32 | */ 33 | -------------------------------------------------------------------------------- /src/components/TypesList/sinonMatcherTypesList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of event types that are used in the AutoComplete component to help with the auto complete process 3 | * This list is imported in the AutoComplete functionality for assertion matcher autocomplete. 4 | */ 5 | interface MLCType { 6 | name: string 7 | } 8 | 9 | //!SINON MATCHERS 10 | export const sinonMatcherTypesList: Array = [ 11 | { 12 | name: 'called', //sinon.assert.called (sinon) 13 | }, 14 | { 15 | name: 'callCount',//spy.callCount (sinon) 16 | }, 17 | { 18 | name: 'calledWith',//spy.calledWith (sinon) 19 | }, 20 | { 21 | name: 'neverCalledWith',//spy.neverCalledWith (sinon) 22 | }, 23 | { 24 | name: 'returned',//spy.returned (sinon) 25 | }, 26 | ]; 27 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/DescribeBlock/DescribeRenderer.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #describeBlocklight { 6 | display: flex; 7 | flex-direction: column; 8 | gap: 8px; 9 | position: relative; 10 | background-color: white; 11 | border-radius: 3px; 12 | box-shadow: 1px 1px 5px gray; 13 | display: flex; 14 | flex-direction: column; 15 | border-radius: 4px; 16 | z-index: 3; 17 | margin-bottom: 10px; 18 | button { 19 | margin: 2px; 20 | color: black; 21 | } 22 | 23 | --describe-bg: #{$lighter-mint}; 24 | --button-color: black; 25 | } 26 | 27 | #describeBlockdark { 28 | display: flex; 29 | flex-direction: column; 30 | gap: 8px; 31 | position: relative; 32 | background-color: $chromegray-less-light; 33 | border-radius: 3px; 34 | box-shadow: 1px 1px 5px gray; 35 | display: flex; 36 | flex-direction: column; 37 | border-radius: 4px; 38 | z-index: 3; 39 | margin-bottom: 10px; 40 | button { 41 | margin: 2px; 42 | color: white; 43 | } 44 | 45 | --describe-bg: #{$salmon}; 46 | --button-color: white; 47 | } 48 | 49 | .describeClose { 50 | position: absolute; 51 | top: 10px; 52 | right: 10px; 53 | font-size: 1.5rem; 54 | z-index: 20; 55 | transition: 250ms; 56 | color: white; 57 | 58 | &:hover { 59 | color: red; 60 | cursor: pointer; 61 | font-size: 1.75rem; 62 | font-weight: bold; 63 | } 64 | } 65 | 66 | .describeInputContainer { 67 | width: 100%; 68 | padding: 10px; 69 | background-color: var(--describe-bg); 70 | border-radius: 4px; 71 | 72 | input { 73 | color: white; 74 | width: 100%; 75 | } 76 | } 77 | /*.describeInputContainer .MuiFormControl-root { 78 | width: 100%; 79 | css-1nrlq1o-MuiFormControl-root 80 | }*/ 81 | 82 | .describeChildrenSection { 83 | padding-left: 30px; 84 | } 85 | 86 | .addIt { 87 | color: white; 88 | padding: 0.5rem; 89 | border-radius: 5px; 90 | background-color: $mint; 91 | // padding: 92 | 93 | &:hover { 94 | background-color: white; 95 | color: $mint; 96 | } 97 | } 98 | 99 | /*Animation for Describe block*/ 100 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/MockData/MockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #mockDatalight { 6 | @include box-styling; 7 | padding: 5px 10px 10px 8px; 8 | background-color: $light-gray2; 9 | 10 | hr { 11 | border: 1px solid $light-gray; 12 | margin-top: 0; 13 | } 14 | 15 | button:hover { 16 | color: $mint; 17 | } 18 | button { 19 | font-size: 12px; 20 | width: 30%; 21 | padding-top: 5px; 22 | border: none; 23 | font-family: $raleway; 24 | font-weight: bold; 25 | text-align: left; 26 | } 27 | 28 | input { 29 | width: 38%; 30 | } 31 | } 32 | 33 | #mockDatadark { 34 | @include box-styling; 35 | padding: 5px 10px 10px 8px; 36 | background-color: $chromegray-less-light; 37 | color: white; 38 | 39 | hr { 40 | border: 1px solid $light-gray; 41 | margin-top: 0; 42 | } 43 | 44 | button:hover { 45 | color: $mint; 46 | } 47 | button { 48 | font-size: 12px; 49 | width: 30%; 50 | padding-top: 5px; 51 | border: none; 52 | font-family: $raleway; 53 | font-weight: bold; 54 | text-align: left; 55 | } 56 | 57 | input { 58 | width: 38%; 59 | } 60 | } 61 | 62 | #close { 63 | float: right; 64 | } 65 | #mockDataHeader { 66 | padding: 10px 0; 67 | vertical-align: middle; 68 | } 69 | 70 | #keys { 71 | font-size: 13px; 72 | margin-bottom: 0; 73 | display: flex; 74 | width: 61%; 75 | justify-content: space-between; 76 | } 77 | 78 | #keyList { 79 | margin-top: 5px; 80 | } 81 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/MockData/MockDataKey.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | 3 | #mockDataKey { 4 | 5 | background-color: $light-gray2; 6 | img { 7 | width: 15px; 8 | height: 15px; 9 | cursor: pointer; 10 | } 11 | 12 | input { 13 | width: 50%; 14 | display: inline-block; 15 | margin-right: 20px; 16 | } 17 | 18 | select { 19 | width: 38%; 20 | height: 25px; 21 | margin-right: 10px; 22 | background-color: white; 23 | border: 1px solid $light-gray; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/MockData/MockDataKey.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the data for each field key and type in the card for mock data 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from './MockDataKey.module.scss'; 7 | import { deleteMockDataKey, updateMockDataKey } from '../../../context/actions/mockDataActions'; 8 | import { MockDataKeyProps } from '../../../utils/mockTypes'; 9 | 10 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 11 | 12 | const MockDataKey = ({ dispatchToMockData, mockDatumId, mockDatumKeyId, fieldKey, fieldType }: MockDataKeyProps) => { 13 | const handleChangeDelete = (e: React.MouseEvent) => { 14 | e.stopPropagation(); 15 | dispatchToMockData(deleteMockDataKey(mockDatumId, mockDatumKeyId)); 16 | }; 17 | 18 | const handleChangeUpdateFieldKey = (e: React.BaseSyntheticEvent) => { 19 | e.stopPropagation(); 20 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, e.target.value, fieldType)); 21 | }; 22 | 23 | const handleChangeUpdateFieldType = (e: React.BaseSyntheticEvent) => { 24 | e.stopPropagation(); 25 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, fieldKey, e.target.value)); 26 | }; 27 | 28 | return ( 29 |
30 |
31 | 37 | 52 | delete 53 |
54 |
55 | ); 56 | }; 57 | 58 | export default MockDataKey; 59 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/Render/Prop.module.scss: -------------------------------------------------------------------------------- 1 | @import './../../../assets/stylesheets/colors.scss'; 2 | 3 | #renderPropsFlexBoxlight { 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | color: black; 8 | 9 | input { 10 | width: 240px; 11 | margin: 0 4px 4px 0px; 12 | padding: 10px; 13 | } 14 | 15 | img { 16 | margin-bottom: 5px; 17 | } 18 | } 19 | 20 | #renderPropsFlexBoxdark { 21 | display: flex; 22 | justify-content: center; 23 | align-items: center; 24 | color: white; 25 | 26 | input { 27 | width: 240px; 28 | margin: 0 4px 4px 0px; 29 | padding: 10px; 30 | } 31 | 32 | img { 33 | margin-bottom: 5px; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/UpdatedReactTestComponent/SetupTeardownBlock/SetupTeardownBlock.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/fonts.scss'; 2 | @import '../../../assets/stylesheets/colors.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | .setupTeardownBlockLight { 6 | display: flex; 7 | flex-direction: column; 8 | gap: 8px; 9 | position: relative; 10 | background-color: white; 11 | border-radius: 3px; 12 | box-shadow: 1px 1px 5px gray; 13 | z-index: 3; 14 | margin-bottom: 10px; 15 | 16 | button { 17 | margin: 2px; 18 | color: black; 19 | } 20 | 21 | --setupTeardown-bg: #{$lighter-mint}; 22 | --button-color: black; 23 | } 24 | 25 | .setupTeardownBlockDark { 26 | display: flex; 27 | flex-direction: column; 28 | gap: 8px; 29 | position: relative; 30 | background-color: $chromegray-less-light; 31 | border-radius: 3px; 32 | box-shadow: 1px 1px 5px gray; 33 | z-index: 3; 34 | margin-bottom: 10px; 35 | 36 | button { 37 | margin: 2px; 38 | color: white; 39 | } 40 | 41 | --setupTeardown-bg: #{$salmon}; 42 | --button-color: white; 43 | } 44 | 45 | .closeIcon { 46 | position: absolute; 47 | top: 10px; 48 | right: 10px; 49 | font-size: 1.5rem; 50 | z-index: 20; 51 | transition: 250ms; 52 | color: white; 53 | 54 | &:hover { 55 | color: red; 56 | cursor: pointer; 57 | font-size: 1.75rem; 58 | font-weight: bold; 59 | } 60 | } 61 | 62 | .setupTeardownInputContainer { 63 | width: 100%; 64 | padding: 10px; 65 | background-color: var(--setupTeardown-bg); 66 | border-radius: 4px; 67 | 68 | input { 69 | color: white; 70 | } 71 | } 72 | 73 | .addButton { 74 | color: white; 75 | padding: 0.5rem; 76 | border-radius: 5px; 77 | background-color: rgba(70, 88, 41, 0.133); 78 | 79 | //background-color: $mint; 80 | 81 | &:hover { 82 | background-color: white; 83 | color: $mint; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/components/UploadTest/UploadTest.module.scss: -------------------------------------------------------------------------------- 1 | @import './../../assets/stylesheets/colors.scss'; 2 | 3 | .navBtn { 4 | padding: 0; 5 | border: 0; 6 | margin-top: 15px; 7 | margin-bottom: 40px; 8 | cursor: pointer; 9 | background-color: transparent; 10 | :focus { 11 | outline: 2px solid darkblue; 12 | } 13 | } 14 | 15 | .icons { 16 | width: 28px; 17 | height: 28px; 18 | } 19 | 20 | #saveTestBtn { 21 | margin-top: 10px; 22 | padding-left: 1rem; 23 | font-size: 12px; 24 | text-align: left; 25 | width: 250px; 26 | height: 1.5rem; 27 | color: $dark-gray; 28 | box-shadow: none; 29 | cursor: pointer; 30 | -webkit-appearance: none; 31 | -moz-appearance: none; 32 | :focus { 33 | outline: 2px solid darkblue; 34 | } 35 | } 36 | 37 | #saveTestBtn:focus { 38 | outline: 2px solid darkblue; 39 | } 40 | 41 | .tooltip { 42 | visibility: hidden; 43 | width: 120px; 44 | background: black; 45 | color: white; 46 | position: absolute; 47 | padding: 5px 0; 48 | text-align: center; 49 | border-radius: 8px; 50 | margin: 0 auto; 51 | z-index: 3; 52 | } 53 | 54 | .navBtn:hover .tooltip { 55 | visibility: visible; 56 | margin-left: 5px; 57 | } 58 | 59 | .navBtn:active .tooltip { 60 | visibility: hidden; 61 | } 62 | -------------------------------------------------------------------------------- /src/components/UploadTest/UploadTest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * functionality to save a test into the database 3 | * 4 | * TODO: Tests are not currently saved to DB. 5 | */ 6 | 7 | // import React, { useState } from 'react'; 8 | // import styles from './UploadTest.module.scss'; 9 | // import UploadTestModal from '../Modals/UploadTestModal'; 10 | 11 | // const UploadTest = ({ testType }) => { 12 | // const [uploadTestModalIsOpen, setUploadTestModalIsOpen] = useState(false); 13 | 14 | // const handleOpenUploadTestModal = () => { 15 | // setUploadTestModalIsOpen(true); 16 | // }; 17 | 18 | // return ( 19 | // <> 20 | // 23 | // {uploadTestModalIsOpen ? ( 24 | // 29 | // ) : null} 30 | // 31 | // ); 32 | // }; 33 | 34 | // export default UploadTest; 35 | -------------------------------------------------------------------------------- /src/components/UserGuideView/ReactInstructions.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | 4 | /** 5 | * Renders the video guide in the UserGuideView Component (Purely for when viewing the React TestType). 6 | * @returns { JSX.Element } Renders the ReactInstructions component 7 | */ 8 | const ReactInstructions = (): JSX.Element => { 9 | 10 | return ( 11 |
12 | 13 |
14 | ); 15 | }; 16 | 17 | export default ReactInstructions; -------------------------------------------------------------------------------- /src/components/UserGuideView/UserGuideView.module.scss: -------------------------------------------------------------------------------- 1 | // import the stylesheets for colors and fonts 2 | @import '../../assets/stylesheets/colors.scss'; 3 | @import '../../assets/stylesheets/fonts.scss'; 4 | 5 | .instructions{ 6 | font-family: $openSans; 7 | } 8 | 9 | #instructionsDiv{ 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | } 14 | 15 | #userGuide{ 16 | * { 17 | transition: color 0.0s !important; 18 | } 19 | } 20 | 21 | #userGuidelight { 22 | background-color: white !important; 23 | --container-bg: #{$mint}; 24 | --container-border: #{$eggshell-opaque}; 25 | --accordion-bg: #24A19C; 26 | --accordion-details-bg: white; 27 | --accordion-color: black; 28 | } 29 | 30 | #userGuidedark { 31 | background-color: #{$chromegray-opaque} !important; 32 | color: white; 33 | --container-bg: #{$darkslategrey}; 34 | --container-border: #{$mint}; 35 | --accordion-bg: #{$chromegray}; 36 | --accordion-details-bg: #{$chromegray-light}; 37 | --accordion-color: white; 38 | } 39 | -------------------------------------------------------------------------------- /src/components/UserGuideView/UserGuideView.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import styles from './UserGuideView.module.scss'; 3 | import Instructions from './Instructions'; 4 | import { GlobalContext } from '../../context/reducers/globalReducer'; 5 | 6 | // const { ipcRenderer } = require('electron'); 7 | /** 8 | * 9 | * @param { } theme 10 | * @returns { JSX.Element } renders the UserGuide component 11 | */ 12 | const UserGuideView = ({ theme }: { theme: string }): JSX.Element => { 13 | const [{ testCase }] = useContext(GlobalContext); 14 | return ( 15 |
16 |
17 |
18 | 19 |
20 | ); 21 | }; 22 | 23 | export default UserGuideView; 24 | -------------------------------------------------------------------------------- /src/components/VueTestComponent/MockData/MockData.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | @import '../../../assets/stylesheets/fonts.scss'; 3 | @import '../../../pages/LeftPanel/LeftPanel.module.scss'; 4 | 5 | #mockDatalight { 6 | @include box-styling; 7 | padding: 5px 10px 10px 8px; 8 | background-color: $light-gray2; 9 | 10 | hr { 11 | border: 1px solid $light-gray; 12 | margin-top: 0; 13 | } 14 | 15 | button:hover { 16 | color: $mint; 17 | } 18 | button { 19 | font-size: 12px; 20 | width: 30%; 21 | padding-top: 5px; 22 | border: none; 23 | font-family: $raleway; 24 | font-weight: bold; 25 | text-align: left; 26 | } 27 | 28 | input { 29 | width: 38%; 30 | } 31 | } 32 | 33 | #mockDatadark { 34 | @include box-styling; 35 | padding: 5px 10px 10px 8px; 36 | background-color: $chromegray-less-light; 37 | color: white; 38 | 39 | hr { 40 | border: 1px solid $light-gray; 41 | margin-top: 0; 42 | } 43 | 44 | button:hover { 45 | color: $mint; 46 | } 47 | button { 48 | font-size: 12px; 49 | width: 30%; 50 | padding-top: 5px; 51 | border: none; 52 | font-family: $raleway; 53 | font-weight: bold; 54 | text-align: left; 55 | } 56 | 57 | input { 58 | width: 38%; 59 | } 60 | } 61 | 62 | #close { 63 | float: right; 64 | } 65 | #mockDataHeader { 66 | padding: 10px 0; 67 | vertical-align: middle; 68 | } 69 | 70 | #keys { 71 | font-size: 13px; 72 | margin-bottom: 0; 73 | display: flex; 74 | width: 61%; 75 | justify-content: space-between; 76 | } 77 | 78 | #keyList { 79 | margin-top: 5px; 80 | } 81 | -------------------------------------------------------------------------------- /src/components/VueTestComponent/MockData/MockDataKey.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * the data for each field key and type in the card for mock data 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from './MockDataKey.module.scss'; 7 | import { deleteMockDataKey, updateMockDataKey } from '../../../context/actions/mockDataActions'; 8 | 9 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 10 | 11 | const MockDataKey = ({ dispatchToMockData, mockDatumId, mockDatumKeyId, fieldKey, fieldType }) => { 12 | const handleChangeDelete = (e) => { 13 | e.stopPropagation(); 14 | dispatchToMockData(deleteMockDataKey(mockDatumId, mockDatumKeyId)); 15 | }; 16 | 17 | const handleChangeUpdateFieldKey = (e) => { 18 | e.stopPropagation(); 19 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, e.target.value, fieldType)); 20 | }; 21 | 22 | const handleChangeUpdateFieldType = (e) => { 23 | e.stopPropagation(); 24 | dispatchToMockData(updateMockDataKey(mockDatumId, mockDatumKeyId, fieldKey, e.target.value)); 25 | }; 26 | 27 | return ( 28 |
29 |
30 | 36 | 51 | delete 52 |
53 |
54 | ); 55 | }; 56 | 57 | export default MockDataKey; 58 | -------------------------------------------------------------------------------- /src/components/VueTestComponent/MockData/MockDataKey.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../assets/stylesheets/colors.scss'; 2 | 3 | #mockDataKey { 4 | margin: 0 10px 5px 12px; 5 | img { 6 | width: 15px; 7 | height: 15px; 8 | cursor: pointer; 9 | } 10 | 11 | input { 12 | width: 50%; 13 | display: inline-block; 14 | margin-right: 20px; 15 | } 16 | 17 | select { 18 | width: 38%; 19 | height: 25px; 20 | margin-right: 10px; 21 | background-color: white; 22 | border: 1px solid $light-gray; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/components/VueTestComponent/Render/Prop.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * ? 3 | */ 4 | 5 | import React from 'react'; 6 | import styles from '../../ReactTestComponent/Render/Prop.module.scss'; 7 | import { deleteProp, updateProp } from '../../../context/actions/frontendFrameworkTestCaseActions'; 8 | import AutoCompleteMockData from '../../AutoComplete/AutoCompleteMockData'; 9 | 10 | const minusIcon = require('../../../assets/images/minus-box-outline.png'); 11 | 12 | const Prop = ({ statementId, propId, propKey, propValue, dispatchToTestCase }) => { 13 | const handleClickDeleteProp = (e) => { 14 | e.stopPropagation(); 15 | dispatchToTestCase(deleteProp(statementId, propId)); 16 | }; 17 | 18 | const handleChangeUpdatePropKey = (e) => { 19 | e.stopPropagation(); 20 | dispatchToTestCase(updateProp(statementId, propId, e.target.value, propValue)); 21 | }; 22 | 23 | const handleChangeUpdatePropValue = (e) => { 24 | e.stopPropagation(); 25 | dispatchToTestCase(updateProp(statementId, propId, propKey, e.target.value)); 26 | }; 27 | 28 | return ( 29 |
30 | 31 | 38 | {/* */} 47 | delete 48 |
49 | ); 50 | }; 51 | 52 | export default Prop; 53 | -------------------------------------------------------------------------------- /src/context/actions/cypressTestCaseActions.ts: -------------------------------------------------------------------------------- 1 | // Create cypressActionTypes and action creators -------------------------------------------------------------------------------- /src/context/actions/mockDataActions.ts: -------------------------------------------------------------------------------- 1 | export const actionTypes = { 2 | TOGGLE_MOCK_DATA: 'TOGGLE_MOCK_DATA', 3 | ADD_MOCK_DATA: 'ADD_MOCK_DATA', 4 | DELETE_MOCK_DATA: 'DELETE_MOCK_DATA', 5 | UPDATE_MOCK_DATA_NAME: 'UPDATE_MOCK_DATA_NAME', 6 | 7 | ADD_MOCK_DATA_KEY: 'ADD_MOCK_DATA_KEY', 8 | DELETE_MOCK_DATA_KEY: 'DELETE_MOCK_DATA_KEY', 9 | UPDATE_MOCK_DATA_KEY: 'UPDATE_MOCK_DATA_KEY', 10 | 11 | CLEAR_MOCK_DATA: 'CLEAR_MOCK_DATA', 12 | REPLACE_TEST: 'REPLACE_TEST', 13 | }; 14 | 15 | export const toggleMockData = () => ({ 16 | type: actionTypes.TOGGLE_MOCK_DATA, 17 | }); 18 | 19 | export const createMockData = () => ({ 20 | type: actionTypes.ADD_MOCK_DATA, 21 | }); 22 | 23 | export const deleteMockData = (id: number) => ({ 24 | type: actionTypes.DELETE_MOCK_DATA, 25 | id, 26 | }); 27 | 28 | export const updateMockDataName = (id: number, name: string) => ({ 29 | type: actionTypes.UPDATE_MOCK_DATA_NAME, 30 | id, 31 | name, 32 | }); 33 | 34 | export const addMockDataKey = (id: number) => ({ 35 | type: actionTypes.ADD_MOCK_DATA_KEY, 36 | id, 37 | }); 38 | 39 | export const deleteMockDataKey = (mockDatumId: number, mockDatumKeyId: number) => ({ 40 | type: actionTypes.DELETE_MOCK_DATA_KEY, 41 | mockDatumId, 42 | mockDatumKeyId, 43 | }); 44 | 45 | export const updateMockDataKey = (mockDatumId: number, mockDatumKeyId: number, fieldKey: string, fieldType: string) => ({ 46 | type: actionTypes.UPDATE_MOCK_DATA_KEY, 47 | mockDatumId, 48 | mockDatumKeyId, 49 | fieldKey, 50 | fieldType, 51 | }); 52 | 53 | export const clearMockData = () => ({ 54 | type: actionTypes.CLEAR_MOCK_DATA, 55 | }); 56 | 57 | export const mockReplaceTest = (testState: object) => ({ 58 | type: actionTypes.REPLACE_TEST, 59 | testState, 60 | }); 61 | -------------------------------------------------------------------------------- /src/context/actions/puppeteerTestCaseActions.ts: -------------------------------------------------------------------------------- 1 | import { PuppeteerStatements } from '../../utils/puppeteerTypes'; 2 | 3 | export const actionTypes = { 4 | TOGGLE_PUPPETEER: 'TOGGLE_PUPPETEER', 5 | CREATE_NEW_PUPPETEER_TEST: 'CREATE_NEW_PUPPETEER_TEST', 6 | DELETE_PUPPETEER_TEST: 'DELETE_PUPPETEER_TEST', 7 | ADD_PUPPETEER_PAINT_TIMING: 'ADD_PUPPETEER_PAINT_TIMING', 8 | DELETE_PUPPETEER_PAINT_TIMING: 'DELETE_PUPPETEER_PAINT_TIMING', 9 | ADD_BROWSER_OPTIONS: 'ADD_BROWSER_OPTIONS', 10 | UPDATE_PAINT_TIMING: 'UPDATE_PAINT_TIMING', 11 | DELETE_BROWSER_OPTION: 'DELETE_BROWSER_OPTION', 12 | UPDATE_BROWSER_OPTION: 'UPDATE_BROWSER_OPTION', 13 | UPDATE_STATEMENTS_ORDER: 'UPDATE_STATEMENTS_ORDER', 14 | OPEN_INFO_MODAL: 'OPEN_INFO_MODAL', 15 | CLOSE_INFO_MODAL: 'CLOSE_INFO_MODAL', 16 | REPLACE_TEST: 'REPLACE_TEST', 17 | }; 18 | 19 | export const togglePuppeteer = () => ({ 20 | type: actionTypes.TOGGLE_PUPPETEER, 21 | }); 22 | 23 | export const createNewPuppeteerTest = () => ({ 24 | type: actionTypes.CREATE_NEW_PUPPETEER_TEST, 25 | }); 26 | 27 | export const deletePuppeteerTest = (id: number) => ({ 28 | type: actionTypes.DELETE_PUPPETEER_TEST, 29 | id, 30 | }); 31 | 32 | export const addPuppeteerPaintTiming = () => ({ 33 | type: actionTypes.ADD_PUPPETEER_PAINT_TIMING, 34 | }); 35 | 36 | export const addBrowserOption = (id: number) => ({ 37 | type: actionTypes.ADD_BROWSER_OPTIONS, 38 | id, 39 | }); 40 | 41 | export const deleteBrowserOption = (id: number, optionId: number) => ({ 42 | type: actionTypes.DELETE_BROWSER_OPTION, 43 | id, 44 | optionId, 45 | }); 46 | 47 | export const updatePaintTiming = (id: number, field: string, value: string) => ({ 48 | type: actionTypes.UPDATE_PAINT_TIMING, 49 | id, 50 | field, 51 | value, 52 | }); 53 | 54 | export const updateBrowserOption = ( 55 | id: number, 56 | field: string, 57 | value: string, 58 | optionId: number 59 | ) => ({ 60 | type: actionTypes.UPDATE_BROWSER_OPTION, 61 | id, 62 | field, 63 | value, 64 | optionId, 65 | }); 66 | 67 | export const updateStatementsOrder = (draggableStatements: Array) => ({ 68 | type: actionTypes.UPDATE_STATEMENTS_ORDER, 69 | draggableStatements, 70 | }); 71 | 72 | export const openInfoModal = () => { 73 | return { type: actionTypes.OPEN_INFO_MODAL }; 74 | }; 75 | 76 | export const closeInfoModal = () => { 77 | return { type: actionTypes.CLOSE_INFO_MODAL }; 78 | }; 79 | 80 | export const puppeteerReplaceTest = (testState: object) => ({ 81 | type: actionTypes.REPLACE_TEST, 82 | testState, 83 | }); 84 | -------------------------------------------------------------------------------- /src/context/actions/secTestCaseActions.ts: -------------------------------------------------------------------------------- 1 | /* ------------------------------ Action Types ------------------------------ */ 2 | 3 | export const actionTypes = { 4 | OPEN_INFO_MODAL: 'OPEN_INFO_MODAL', 5 | CLOSE_INFO_MODAL: 'CLOSE_INFO_MODAL', 6 | CREATE_NEW_SEC_TEST: 'CREATE_NEW_SEC_TEST', 7 | REPLACE_TEST: 'REPLACE_TEST' 8 | }; 9 | 10 | /* --------------------------------- Actions -------------------------------- */ 11 | 12 | export const openInfoModal = () => ({ 13 | type: actionTypes.OPEN_INFO_MODAL, 14 | }); 15 | 16 | export const closeInfoModal = () => ({ 17 | type: actionTypes.CLOSE_INFO_MODAL, 18 | }); 19 | 20 | export const createNewSecTest = () => ({ 21 | type: actionTypes.CREATE_NEW_SEC_TEST, 22 | }); 23 | 24 | export const secReplaceTest = (testState: object) => ({ 25 | type: actionTypes.REPLACE_TEST, 26 | testState, 27 | }); 28 | -------------------------------------------------------------------------------- /src/context/errorHandle/ConfirmDialogue.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Need to provide a buffer before closing blocks in testing UI. Currently, User can 3 | accidentally lose everything with the 4 | press of 1 5 | 6 | 7 | Code was taken from online. 8 | Needs to be broken down., understand, and reconstructed 9 | source of this code: https://plainenglish.io/blog/creating-a-confirm-dialog-in-react-and-material-ui 10 | */ 11 | 12 | import React from 'react'; 13 | import Button from '@material-ui/core/Button'; 14 | import Dialog from '@material-ui/core/Dialog'; 15 | import DialogActions from '@material-ui/core/DialogActions'; 16 | import DialogContent from '@material-ui/core/DialogContent'; 17 | import DialogTitle from '@material-ui/core/DialogTitle'; 18 | 19 | const ConfirmDialog = (props) => { 20 | const { title, children, open, setOpen, onConfirm } = props; 21 | return ( 22 | setOpen(false)} 25 | aria-labelledby="confirm-dialog" 26 | > 27 | {title} 28 | {children} 29 | 30 | 37 | 47 | 48 | 49 | ); 50 | }; 51 | 52 | export default ConfirmDialog; 53 | -------------------------------------------------------------------------------- /src/context/errorHandle/ErrorBoundary.jsx: -------------------------------------------------------------------------------- 1 | /* checked it out online. looks important to hae in app, but 2 | we didn't have the time to implement. Below is 3 | some code taken from online that should be 4 | looked into 5 | source:https://legacy.reactjs.org/docs/error-boundaries.html 6 | */ 7 | 8 | class ErrorBoundary extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { hasError: false }; 12 | } 13 | 14 | static getDerivedStateFromError(error) { 15 | // Update state so the next render will show the fallback UI. 16 | return { hasError: true }; 17 | } 18 | 19 | componentDidCatch(error, errorInfo) { 20 | // You can also log the error to an error reporting service 21 | logErrorToMyService(error, errorInfo); 22 | } 23 | 24 | render() { 25 | if (this.state.hasError) { 26 | // You can render any custom fallback UI 27 | return

Something went wrong.

; 28 | } 29 | 30 | return this.props.children; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/context/reducers/secTestCaseReducer.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { SecTestCaseState, Action } from '../../utils/secTypes'; 3 | import { actionTypes } from '../actions/secTestCaseActions'; 4 | 5 | interface secContext { 6 | isFileDirectoryOpen: null | boolean; 7 | theme: null | string; 8 | dispatchToGlobal:(n: number) => void 9 | }; 10 | 11 | export const SecTestCaseContext: any = createContext([]); 12 | 13 | /* ------------------------- Security Test Case State ------------------------ */ 14 | 15 | export const secTestCaseState: SecTestCaseState = { 16 | modalOpen: true 17 | } 18 | 19 | /* ------------------------- Security Test Case Reducer ------------------------ */ 20 | 21 | export const secTestCaseReducer = (state: SecTestCaseState, action: Action) => { 22 | switch (action.type) { 23 | case actionTypes.OPEN_INFO_MODAL: { 24 | return { 25 | ...state, 26 | modalOpen: true 27 | } 28 | } 29 | case actionTypes.OPEN_INFO_MODAL: { 30 | return { 31 | ...state, 32 | modalOpen: true 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App.jsx'; 4 | 5 | 6 | ReactDOM.render( , 7 | document.getElementById('root')); -------------------------------------------------------------------------------- /src/pages/LeftPanel/LeftPanel.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import styles from './LeftPanel.module.scss'; 3 | import TestFile from '../TestFile/TestFile'; 4 | import { GlobalContext } from '../../context/reducers/globalReducer'; 5 | 6 | /** 7 | * Renders the LeftPanel react component. 8 | * 9 | * This component consists of main page to choose a test along with the individual testing component that you selected. 10 | * @returns { JSX.Element } Returns the LeftPanel react component 11 | */ 12 | const LeftPanel = () => { 13 | //! Testing test Framework context 14 | const [{ theme }] = useContext( 15 | GlobalContext 16 | ); 17 | return ( 18 |
19 | 20 |
21 | ); 22 | 23 | }; 24 | 25 | export default LeftPanel; 26 | -------------------------------------------------------------------------------- /src/pages/RightPanel/RightPanel.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | 3 | #rightPanellight { 4 | flex: 1 2 35%; 5 | height: 100%; 6 | display: flex; 7 | flex-direction: column; 8 | min-width: 480px; 9 | background-color: white; 10 | border-radius: 5px; 11 | } 12 | 13 | #rightPaneldark { 14 | flex: 1 2 35%; 15 | height: 100%; 16 | display: flex; 17 | flex-direction: column; 18 | min-width: 480px; 19 | background-color: #{$chromegray}; 20 | border-radius: 5px; 21 | } 22 | 23 | #tabsContainer { 24 | width: 100%; 25 | } 26 | 27 | .viewContainer{ 28 | flex: 1; 29 | width: 100%; 30 | height: 100%; 31 | } 32 | 33 | #close { 34 | align-self: flex-end; 35 | margin-right: .5rem; 36 | cursor: pointer; 37 | } 38 | 39 | #term { 40 | width: 100%; 41 | height: 100%; 42 | } 43 | 44 | #tabsBox { 45 | background-color: #{$salmon} 46 | } -------------------------------------------------------------------------------- /src/pages/TestFile/TestCard.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import styles from './TestCard.module.scss' 3 | import { GlobalContext } from '../../context/reducers/globalReducer'; 4 | 5 | const TestCard = ({icon, type, description, onClick}) => { 6 | 7 | const [{ theme }] = useContext( 8 | GlobalContext 9 | ); 10 | 11 | return ( 12 |
13 |
14 | {icon} 15 |
16 |
17 |

18 | {type} 19 |

20 |
21 | {description} 22 |
23 |
24 |
25 | ); 26 | }; 27 | 28 | export default TestCard; -------------------------------------------------------------------------------- /src/pages/TestFile/TestCard.module.scss: -------------------------------------------------------------------------------- 1 | @import './../../assets/stylesheets/fonts.scss'; 2 | @import './../../assets/stylesheets/colors.scss'; 3 | 4 | .testCardlight { 5 | display: flex; 6 | background-color: $mint; 7 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; 8 | border-radius: 4px; 9 | width: 100%; 10 | height: 100%; 11 | cursor: pointer; 12 | --card-content-bg: white; 13 | --card-title-color: #{$salmon}; 14 | --card-desc-color: black; 15 | --line-color: #{$mint}; 16 | 17 | &:hover{ 18 | transform: scale(1.01, 1.02); 19 | transition: all 0.5s ease-out; 20 | } 21 | } 22 | 23 | .testCarddark { 24 | display: flex; 25 | background-color: $darkslategrey; 26 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; 27 | border-radius: 4px; 28 | width: 100%; 29 | height: 100%; 30 | cursor: pointer; 31 | --card-content-bg: #{$chromegray}; 32 | --card-title-color: #{$mint}; 33 | --card-desc-color: #{$eggshell}; 34 | --line-color: #{$salmon}; 35 | &:hover{ 36 | transform: scale(1.01, 1.02); 37 | transition: all 0.5s ease-out; 38 | } 39 | } 40 | 41 | .iconLeft { 42 | padding: 10px; 43 | flex: 1 1 30%; 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | 48 | svg { 49 | height: 65%; 50 | width: 65%; 51 | color: white; 52 | max-width: 80px; 53 | max-height: 80px; 54 | } 55 | } 56 | 57 | .contentCard { 58 | display: flex; 59 | flex: 1 1 70%; 60 | flex-direction: column; 61 | align-items: center; 62 | gap: 20px; 63 | background-color: var(--card-content-bg); 64 | border-top-right-radius: 4px; 65 | border-bottom-right-radius: 4px; 66 | } 67 | 68 | .cardTitle { 69 | color: var(--card-title-color); 70 | flex: 1 1 30%; 71 | display: flex; 72 | font-size: 1.25rem; 73 | font-weight: bold; 74 | justify-content: center; 75 | align-items: flex-end; 76 | border-bottom: 2px solid $mint; 77 | width: 100%; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/pages/TestFile/TestFile.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../assets/stylesheets/colors.scss'; 2 | @import '../../assets/stylesheets/fonts.scss'; 3 | 4 | #testFileContainer { 5 | display: flex; 6 | flex-direction: column; 7 | min-height: 100vh; 8 | gap: 30px; 9 | width: 100%; 10 | padding: 10% 10% 10% 10%; 11 | } 12 | 13 | #testFileContainer > * { 14 | padding: 20px; 15 | } 16 | 17 | 18 | #chooseTest{ 19 | font-size: 1.8rem; 20 | font-weight: bold; 21 | font-family: $raleway; 22 | color: var(--choose-test-color); 23 | } 24 | 25 | #testCardsContainer { 26 | display: grid; 27 | grid-template-columns: repeat(2, 1fr); 28 | grid-template-rows: repeat(6, 1fr); 29 | grid-column-gap: 30px; 30 | grid-row-gap: 20px; 31 | justify-items: center; 32 | height: 100%; 33 | width: 100%; 34 | } -------------------------------------------------------------------------------- /src/utils/accTypes.ts: -------------------------------------------------------------------------------- 1 | export type allIdsType = { 2 | [key: string]: string[], 3 | } 4 | 5 | export interface AccTestCaseState { 6 | modalOpen: boolean; 7 | describeId: number; 8 | itId: number; 9 | statementId: number; 10 | propId: number; 11 | describeBlocks: DescribeBlocks 12 | itStatements: ItStatements; 13 | fileName: string; 14 | filePath: string; 15 | testType: string; 16 | puppeteerUrl: string; 17 | } 18 | 19 | export type ByIdType = { 20 | [key: string | number]: Object, 21 | 22 | } 23 | 24 | export interface DescribeBlocks { 25 | byId: ByIdType; 26 | allIds: Array; 27 | } 28 | export interface ItStatements { 29 | byId: ByIdType; 30 | allIds: allIdsType; 31 | } 32 | export interface Action { 33 | type: string; 34 | id?: string; 35 | draggableStatements?: Array; 36 | index?: number; 37 | text?: string; 38 | itId: string; 39 | describeId: number | string; 40 | reorderedDescribe?: Array; 41 | reorderedIt?: Array; 42 | fileName?: string; 43 | filePath?: string; 44 | testType?: string; 45 | describeBlocks: any[]; 46 | standardTag: string; 47 | catTag: string; 48 | puppeteerUrl?: string, 49 | testState?: string, 50 | } 51 | -------------------------------------------------------------------------------- /src/utils/endpointTypes.ts: -------------------------------------------------------------------------------- 1 | export interface EndpointStatements { 2 | id: number; 3 | type: string; 4 | [key: string]: any; 5 | } 6 | 7 | export interface EndpointTestCaseState { 8 | modalOpen: boolean; 9 | serverFilePath: string; 10 | serverFileName: string; 11 | endpointStatements: EndpointObj[]; 12 | dbFilePath: string; 13 | dbFileName: string; 14 | addDB: boolean | string; 15 | } 16 | 17 | export interface Action { 18 | type: string; 19 | id?: number; 20 | serverFileName?: string; 21 | serverFilePath?: string; 22 | draggableStatements?: Array; 23 | index?: number; 24 | text?: string; 25 | assertion?: Assertion; 26 | db?: string | boolean; 27 | dbFilePath?: string; 28 | dbFileName?: string; 29 | testState?: object; 30 | } 31 | 32 | type EndpointKeyValues = number | string | boolean | Assertion[] | Header[]; 33 | 34 | interface forEndpoint { 35 | [index: string]: EndpointKeyValues; 36 | } 37 | 38 | export interface EndpointObj extends forEndpoint { 39 | id: number; 40 | type: string; 41 | testName: string; 42 | method: string; 43 | route: string; 44 | assertions: Assertion[]; 45 | headers: Header[]; 46 | post: boolean; 47 | postData: string; 48 | } 49 | 50 | export interface Assertion { 51 | id: number; 52 | expectedResponse: string; 53 | value: string; 54 | matcher: string; 55 | not: boolean; 56 | } 57 | 58 | export interface Header { 59 | id: number; 60 | headerName: string; 61 | headerValue: string; 62 | } 63 | 64 | export type EventTarget = { 65 | target: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; 66 | }; 67 | export interface EndpointTestMenuProps { 68 | dispatchToEndpointTestCase: (action: object) => void; 69 | } 70 | export interface EndpointTestStatementsProps extends EndpointTestMenuProps { 71 | endpointStatements: Array; 72 | } 73 | -------------------------------------------------------------------------------- /src/utils/globalTypes.ts: -------------------------------------------------------------------------------- 1 | export interface GlobalActionTypes { 2 | type: string, 3 | url?: string, 4 | load?: string, 5 | fileTree?: string, 6 | display?: string, 7 | filePath?: string, 8 | fileName?: string, 9 | projectFilePath?: string, 10 | filePathMap?: string, 11 | testCase?: string, 12 | testString?: string, 13 | docsUrl?: string, 14 | validCode?: boolean, 15 | tabIndex?: number, 16 | testState?: Object, 17 | guestState?: string, 18 | theme?: string, 19 | fileDirectoryOpen?: string, 20 | testFramework?: 'jest' | 'cypress' | 'mocha' | 'sinon'; 21 | } 22 | 23 | export interface GlobalStateTypes { 24 | url: string, 25 | projectUrl: (null | string), 26 | isProjectLoaded: boolean, 27 | fileTree: (null | File[]), 28 | isFileDirectoryOpen: boolean, 29 | isRightPanelOpen: boolean, 30 | rightPanelDisplay: string, 31 | isFolderOpen: isFolderOpenType, 32 | isFileHighlighted: string, 33 | projectFilePath: string, 34 | filePathMap: filePathMapType, 35 | file: string, 36 | testCase: string, 37 | docsOpen: boolean, 38 | isTestModalOpen: boolean, 39 | exportBool: boolean, 40 | fileName: string, 41 | filePath: string, 42 | validCode: boolean, 43 | tabIndex: number, 44 | isGuest: boolean, 45 | theme: any, 46 | testFramework: 'jest' | 'cypress' | 'mocha' | 'sinon'; //! added new global testframework 47 | } 48 | 49 | /** 50 | * Fixing input validation due to indexing errors. 51 | */ 52 | export interface extensionCheckerType { 53 | [key: string]: number, 54 | } 55 | 56 | export interface isFolderOpenType { 57 | [key: string]: boolean; 58 | } 59 | 60 | 61 | export interface filePathMapType { 62 | [key: string]: Object 63 | } 64 | 65 | /* Interface for Modal files and fileTree */ 66 | export interface File { 67 | fileName: string; 68 | filePath: string; 69 | files: File[]; 70 | } 71 | 72 | // Interface for filePathMap 73 | export interface FilePathMap { 74 | [key: string]: string; 75 | } -------------------------------------------------------------------------------- /src/utils/graphQLTypes.ts: -------------------------------------------------------------------------------- 1 | export interface GraphQLStatements { 2 | id: number; 3 | type: string; 4 | [key: string]: any; 5 | } 6 | 7 | export interface GraphQLTestCaseState { 8 | modalOpen: boolean; 9 | serverFilePath: string; 10 | serverFileName: string; 11 | // graphQLStatements: GraphQLObj[]; 12 | graphQLStatements: any; 13 | dbFilePath: string; 14 | dbFileName: string; 15 | addDB: boolean | string; 16 | } 17 | 18 | export interface Action { 19 | type: string; 20 | id?: number; 21 | serverFileName?: string; 22 | serverFilePath?: string; 23 | draggableStatements?: Array; 24 | index?: number; 25 | text?: string; 26 | assertion?: Assertion; 27 | db?: string | boolean; 28 | dbFilePath?: string; 29 | dbFileName?: string; 30 | testState?: object; 31 | } 32 | 33 | type GraphQLKeyValues = number | string | boolean | Assertion[] | Header[]; 34 | 35 | interface forGraphQL { 36 | [index: string]: GraphQLKeyValues; 37 | } 38 | 39 | export interface GraphQLObj extends forGraphQL { 40 | id: number; 41 | type: string; 42 | testName: string; 43 | method: string; 44 | route: string; 45 | assertions: Assertion[]; 46 | headers: Header[]; 47 | post: boolean; 48 | postData: string; 49 | } 50 | 51 | export interface Assertion { 52 | id: number; 53 | expectedResponse: string; 54 | value: string; 55 | matcher: string; 56 | not: boolean; 57 | } 58 | 59 | export interface Header { 60 | id: number; 61 | headerName: string; 62 | headerValue: string; 63 | } 64 | 65 | export type EventTarget = { 66 | target: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; 67 | }; 68 | export interface GraphQLTestMenuProps { 69 | dispatchToGraphQLTestCase: (action: object) => void; 70 | } 71 | export interface GraphQLTestStatementsProps extends GraphQLTestMenuProps { 72 | graphQLStatements: Array; 73 | } 74 | -------------------------------------------------------------------------------- /src/utils/mockTypes.ts: -------------------------------------------------------------------------------- 1 | export interface MockDataArrayType { 2 | id: number; 3 | fieldKeys: Array; 4 | name: string; 5 | } 6 | 7 | export interface MockDatumType { 8 | id: number, 9 | name: string, 10 | fieldKeys: Array, 11 | content: string, 12 | type: string, 13 | } 14 | 15 | export interface MockDataProps { 16 | mockDatumId: number, 17 | dispatchToMockData: React.Dispatch, 18 | fieldKeys: Array 19 | } 20 | 21 | export interface DispatchMock { 22 | type: string, 23 | id?: number, 24 | name?: string, 25 | } 26 | 27 | export interface MockDataTypes { 28 | mockData: Array, 29 | hasMockData: boolean, 30 | } 31 | 32 | export interface KeyType { 33 | id: number, 34 | fieldKey: string, 35 | fieldType: string, 36 | } 37 | 38 | export interface MockDataKeyProps { 39 | dispatchToMockData: React.Dispatch, 40 | mockDatumId: number, 41 | mockDatumKeyId: number, 42 | fieldKey: string, 43 | fieldType: string 44 | } 45 | 46 | export interface KeyDispatchMock { 47 | mockDatumId: number, 48 | mockDatumKeyId: number, 49 | fieldKey?: string, 50 | fieldType?: string, 51 | } -------------------------------------------------------------------------------- /src/utils/puppeteerTypes.ts: -------------------------------------------------------------------------------- 1 | export interface PuppeteerTestMenuProps { 2 | dispatchToPuppeteerTestCase: (action: object) => void; 3 | } 4 | 5 | export interface PuppeteerTestModalProps { 6 | isPuppeteerModalOpen: boolean; 7 | closePuppeteerModal: () => void; 8 | } 9 | 10 | export interface PuppeteerTestStatementsProps extends PuppeteerTestMenuProps { 11 | puppeteerStatements: Array; 12 | } 13 | 14 | export interface PuppeteerTestCaseState { 15 | puppeteerStatements: Array; 16 | statementId: number; 17 | } 18 | 19 | export interface PuppeteerStatements { 20 | id: number; 21 | type: string; 22 | // paintTiming: PuppeteerStatements; 23 | describe: string; 24 | url: string; 25 | browserOptions: Array; 26 | hasBrowserOption: boolean; 27 | browserOptionId: number; 28 | [key: string]: any; 29 | } 30 | 31 | export interface BrowserOptions { 32 | id: number; 33 | optionKey: string; 34 | optionValue: string; 35 | [key: string]: any; 36 | } 37 | 38 | export interface paintTimingType { 39 | id: number, 40 | firstPaintIt?: string, 41 | firstPaintTime?: number, 42 | FCPIt?: string, 43 | FCPTime?: number, 44 | LCPIt?: string, 45 | LCPTime?: number, 46 | } 47 | 48 | export type PuppeteerAction = 49 | | { 50 | type: 51 | | 'TOGGLE_PUPPETEER' 52 | | 'CREATE_NEW_PUPPETEER_TEST' 53 | | 'ADD_PUPPETEER_PAINT_TIMING' 54 | | 'OPEN_INFO_MODAL' 55 | | 'CLOSE_INFO_MODAL' 56 | | 'REPLACE_TEST'; testState: any 57 | } 58 | | { type: 'DELETE_PUPPETEER_TEST' | 'ADD_BROWSER_OPTIONS'; id: number } 59 | | { type: 'DELETE_BROWSER_OPTION'; id: number; optionId: number } 60 | | { type: 'UPDATE_PAINT_TIMING'; id: number; field: string; value: string } 61 | | { type: 'UPDATE_BROWSER_OPTION'; id: number; field: string; value: string; optionId: number } 62 | | { type: 'UPDATE_STATEMENTS_ORDER'; draggableStatements: Array } 63 | -------------------------------------------------------------------------------- /src/utils/reactTestCase/cypress.ts: -------------------------------------------------------------------------------- 1 | 2 | export type SelectorType = 3 | 'get'| 'find'|'contains'| 'within'| 4 | 'parent'| 'children'| 'filter'| 'eq'| 5 | 'getByTestId'| 'getByRole'; 6 | 7 | export type ActionType = 8 | 'click'|'dblclick'|'rightclick'|'type'| 9 | 'clear'|'check'| 'uncheck'| 'select'| 10 | 'scrollIntoView'| 'trigger'| 'focus'| 11 | 'blur'|'invoke'; 12 | 13 | 14 | // One step in a Cypress command chain, 15 | // { selectorType: "get", selectorValue: "#name", actionType: "type", actionValue: "Alice" } 16 | export interface CypressCommandStep { 17 | id?: string; // unique id 18 | selectorType: SelectorType; 19 | selectorValue: string; // "#submitBtn" 20 | actionType?: ActionType; 21 | actionValue?: string; // "/Welcome/i", "hello@example.com" 22 | } 23 | 24 | // If you need to store an entire “action statement” of Cypress 25 | export interface CypressTestActionStatement { 26 | id: string; 27 | commandChain: CypressCommandStep[]; 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/reactTestCase/index.ts: -------------------------------------------------------------------------------- 1 | 2 | // src/utils/reactTestCase/index.ts 3 | 4 | export * from "./state"; 5 | export * from "./ui"; 6 | export * from "./cypress"; 7 | export * from "./matchers"; 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/utils/secTypes.ts: -------------------------------------------------------------------------------- 1 | export interface SecTestCaseState { 2 | modalOpen: boolean; 3 | } 4 | 5 | export interface Action { 6 | type: string; 7 | } -------------------------------------------------------------------------------- /src/utils/terminalTypes.ts: -------------------------------------------------------------------------------- 1 | export interface TerminalType { 2 | fontSize: number; 3 | rows: number; 4 | fontFamily?: string; 5 | theme?: { 6 | background?: string; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /stats.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/stats.json -------------------------------------------------------------------------------- /temporaryDump: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-source-labs/Spearmint/514625cf1e494dc8356f661fbc42e280d37ec955/temporaryDump -------------------------------------------------------------------------------- /test/mochaTest.js: -------------------------------------------------------------------------------- 1 | import ReactTestCase.tsx from '../src/components/TestCase/ReactTestCase.tsx'; 2 | import React from 'react'; 3 | import { build, fake } from 'test-data-bot'; 4 | import mocha from 'mocha'; 5 | import chai from 'chai'; 6 | import chai - dom from 'chai-dom'; 7 | 8 | 9 | describe('should render ReactTestCase component', () => { 10 | it('displays main component', () => { 11 | expect( 12 | ).not.to.be(); 13 | const {} = render(); 14 | }) 15 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext", "es2015"], 4 | "allowJs": true, 5 | "allowSyntheticDefaultImports": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "strict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "moduleResolution": "node", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "noEmit": true, 14 | "jsx": "react", 15 | "types": ["node", "jest"], 16 | }, 17 | "include": ["src", "declaration.d.ts"] 18 | } -------------------------------------------------------------------------------- /webpack.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import webpack from 'webpack'; 3 | //const BundleAnalyzerPlugin = 4 | //require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | const config: webpack.Configuration = { 7 | mode: 'development', 8 | entry: './src/index.js', 9 | devtool: 'inline-source-map', 10 | target: 'electron-renderer', 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(ts|js)x?$/, 15 | exclude: /node_modules/, 16 | use: { 17 | loader: 'babel-loader', 18 | options: { 19 | presets: [ 20 | '@babel/preset-env', 21 | '@babel/preset-react', 22 | '@babel/preset-typescript', 23 | ], 24 | }, 25 | }, 26 | }, 27 | { 28 | test: [/\.s[ac]ss$/i, /\.css$/i], 29 | use: [ 30 | // Creates `style` nodes from JS strings 31 | 'style-loader', 32 | // Translates CSS into CommonJS 33 | 'css-loader', 34 | // Compiles Sass to CSS 35 | 'sass-loader', 36 | ], 37 | }, 38 | { 39 | test: [/\.png/, /\.svg/], 40 | type: 'asset/resource', 41 | }, 42 | ], 43 | }, 44 | resolve: { 45 | extensions: ['.tsx', '.jsx', '.ts', '.js'], 46 | }, 47 | output: { 48 | path: path.resolve(__dirname, 'build'), 49 | filename: 'bundle.js', 50 | }, 51 | //plugins: [new BundleAnalyzerPlugin()], 52 | // not sure what this is supposed to do but it no longer works after updating webpack types package 53 | // devServer: { 54 | // contentBase: path.join(__dirname, "build"), 55 | // compress: true, 56 | // port: 4000, 57 | // }, 58 | }; 59 | 60 | export default config; 61 | --------------------------------------------------------------------------------