Skip to content

Commit

Permalink
Merge pull request #421 from ral-facilities/DSEGOG-341-migrate-cra-to…
Browse files Browse the repository at this point in the history
…-vite

DSEGOG-341 Migrate from CRA to Vite
  • Loading branch information
joelvdavies authored Sep 3, 2024
2 parents 7413fd8 + d20ee8f commit 1ce6e85
Show file tree
Hide file tree
Showing 203 changed files with 4,763 additions and 10,473 deletions.
5 changes: 3 additions & 2 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
REACT_APP_OPERATIONSGATEWAY_BUILD_DIRECTORY=/
REACT_APP_E2E_TESTING=false
VITE_APP_OPERATIONS_GATEWAY_BUILD_DIRECTORY=/
VITE_APP_INCLUDE_MSW=false
VITE_APP_BUILD_STANDALONE=false
File renamed without changes.
6 changes: 3 additions & 3 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Install dependencies
run: yarn --immutable
- name: Run linting
run: yarn lint:js
run: yarn lint
- name: Run unit tests
run: yarn test
- name: Upload unit test coverage
Expand Down Expand Up @@ -117,7 +117,7 @@ jobs:
with:
mongodb-version: '5.0'

# Configure correct paths in config files
# Configure correct paths in config files
- name: Configure private key path
run: yq -i ".auth.private_key_path = \"$GITHUB_WORKSPACE/id_rsa\"" .github/ci_config.yml
working-directory: ./operationsgateway-api
Expand Down Expand Up @@ -225,4 +225,4 @@ jobs:
with:
name: playwright-report-real-tests
path: playwright-report/
retention-days: 10
retention-days: 10
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ screenshots/
**/cypress/fixtures/example.json

# production
/build
dist

# misc
.DS_Store
Expand Down
50 changes: 23 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
# operationsgateway

OperationsGateway - user interface for operational data

# Getting Started with Create React App
## Getting Started with Vite

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
This project uses [Vite](https://vitejs.dev/).

## Available Scripts
### Available Scripts

In the project directory, you can run:

### `yarn start`
### `yarn install`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
This will install all the project dependencies. Running `yarn install` at the top
level initialises all the packages, and you will be ready to start development in any of them!

The page will reload if you make edits.\
You will also see any lint errors in the console.
### `yarn dev`

You will need to create a settings file - you can use `./public/operationsgateway-settings.example.json`
as a base. Setting `apiUrl` to `""` enables request mocking via `msw`.
Runs the `dev` script, which runs the app in development mode.
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

### `yarn test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `yarn build`
Runs unit tests for all packages

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
### `yarn e2e`

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
Runs e2e tests for all packages

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `yarn lint`

### `yarn eject`
Lints all packages

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
### `yarn build`

If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Builds the app for production to the `dist` folder.\

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
See the section about [building for production](https://vitejs.dev/guide/build.html) for more information.

## Learn More
### `yarn preview`

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
Deploys a static version of the build from the `dist` directory to port 5001. Use `yarn preview:build` to build and preview it in SciGateway.

To learn React, check out the [React documentation](https://reactjs.org/).
For development purposes, use `yarn preview:build:dev` to build in watch mode so that changes are built automatically.
33 changes: 0 additions & 33 deletions craco.config.js

This file was deleted.

10 changes: 3 additions & 7 deletions cypress.config.js → cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { defineConfig } = require('cypress');
const { removeDirectory } = require('cypress-delete-downloads-folder');
import { defineConfig } from 'cypress';
import { removeDirectory } from 'cypress-delete-downloads-folder';

module.exports = defineConfig({
export default defineConfig({
chromeWebSecurity: false,
video: false,
retries: {
Expand All @@ -12,9 +11,6 @@ module.exports = defineConfig({
e2e: {
setupNodeEvents(on) {
on('task', { removeDirectory });
// https://github.com/bahmutov/cypress-failed-log
require('cypress-failed-log/on')(on);

on('before:browser:launch', (browser, launchOptions) => {
if (browser.family === 'chromium' && browser.name !== 'electron') {
// Set pointer type to fine so that date inputs work properly
Expand Down
11 changes: 7 additions & 4 deletions cypress/e2e/search.cy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HttpResponse } from 'msw';
import { formatDateTimeForApi } from '../support/util';

function getParamsFromUrl(url: string) {
Expand Down Expand Up @@ -1191,12 +1192,14 @@ describe('Search', () => {
// check that if a search drops below the limit the tooltip no longer displays
cy.window().then((window) => {
// Reference global instances set in "src/mocks/browser.js".
const { worker, rest } = window.msw;
const { worker, http } = window.msw;

worker.use(
rest.get('/records/count', (req, res, ctx) => {
return res.once(ctx.status(200), ctx.json(8)); //arbitrary number less than 10
})
http.get(
'/records/count',
() => HttpResponse.json(8, { status: 200 }), //arbitrary number less than 10
{ once: true }
)
);
});

Expand Down
16 changes: 9 additions & 7 deletions cypress/e2e/sessions.cy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { HttpResponse } from 'msw';

function getParamsFromUrl(url: string) {
const paramsString = url.split('?')[1];
const paramMap = new Map();
Expand Down Expand Up @@ -27,13 +29,13 @@ describe('Sessions', () => {
cy.findByTestId('AddCircleIcon').should('exist');
cy.window().then((window) => {
// Reference global instances set in "src/mocks/browser.js".
const { worker, rest } = window.msw;
const { worker, http } = window.msw;

worker.use(
rest.post('/sessions', async (req, res, ctx) => {
http.post('/sessions', async () => {
// return a session without popups
const sessionID = '2';
return res(ctx.status(200), ctx.json(sessionID));
return HttpResponse.json(sessionID, { status: 200 });
})
);
});
Expand All @@ -47,10 +49,10 @@ describe('Sessions', () => {
cy.findByRole('button', { name: 'Save' }).click();

cy.findBrowserMockedRequests({ method: 'POST', url: '/sessions' }).should(
(patchRequests) => {
async (patchRequests) => {
expect(patchRequests.length).equal(1);
const request = patchRequests[0];
expect(JSON.stringify(request.body)).equal(
expect(JSON.stringify(await request.json())).equal(
'{"table":{"columnStates":{},"selectedColumnIds":["timestamp"],"page":0,"resultsPerPage":25,"sort":{}},"search":{"searchParams":{"dateRange":{"toDate":"2024-08-02T14:00:59","fromDate":"2024-08-01T14:00:00"},"shotnumRange":{},"maxShots":50,"experimentID":null}},"plots":{},"filter":{"appliedFilters":[[]]},"windows":{},"selection":{"selectedRows":[]}}'
);

Expand Down Expand Up @@ -198,10 +200,10 @@ describe('Sessions', () => {
cy.findBrowserMockedRequests({
method: 'PATCH',
url: '/sessions/:id',
}).should((patchRequests) => {
}).should(async (patchRequests) => {
expect(patchRequests.length).equal(1);
const request = patchRequests[0];
expect(JSON.stringify(request.body)).equal(
expect(JSON.stringify(await request.json())).equal(
'{"table":{"columnStates":{},"selectedColumnIds":["timestamp","CHANNEL_EFGHI","CHANNEL_FGHIJ","shotnum"],"page":0,"resultsPerPage":25,"sort":{}},"search":{"searchParams":{"dateRange":{"fromDate":"2022-01-06T13:00:00","toDate":"2022-01-09T12:00:59"},"shotnumRange":{"min":7,"max":9},"maxShots":50,"experimentID":{"_id":"19210012-1","end_date":"2022-01-09T12:00:00","experiment_id":"19210012","part":1,"start_date":"2022-01-06T13:00:00"}}},"plots":{},"filter":{"appliedFilters":[[{"type":"channel","value":"shotnum","label":"Shot Number"},{"type":"compop","value":">","label":">"},{"type":"number","value":"7","label":"7"}]]},"windows":{},"selection":{"selectedRows":[]}}'
);
expect(request.url.toString()).to.contain('2');
Expand Down
27 changes: 14 additions & 13 deletions cypress/e2e/table.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getHandleSelector, addInitialSystemChannels } from '../support/util';
import { HttpResponse } from 'msw';
import { addInitialSystemChannels, getHandleSelector } from '../support/util';

const verifyColumnOrder = (columns: string[]): void => {
// check if the first column contains the checkbox
Expand Down Expand Up @@ -262,12 +263,12 @@ describe('Table Component', () => {

cy.window().then((window) => {
// Reference global instances set in "src/mocks/browser.js".
const { worker, rest } = window.msw;
const { worker, http } = window.msw;

worker.use(
rest.get('/records/count', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(50));
})
http.get('/records/count', () =>
HttpResponse.json(50, { status: 200 })
)
);
});

Expand All @@ -279,12 +280,12 @@ describe('Table Component', () => {

cy.window().then(async (window) => {
// Reference global instances set in "src/mocks/browser.js".
const { worker, rest } = window.msw;
const { worker, http } = window.msw;

worker.use(
rest.get('/records/count', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(1000));
})
http.get('/records/count', () =>
HttpResponse.json(1000, { status: 200 })
)
);
});

Expand All @@ -298,12 +299,12 @@ describe('Table Component', () => {

cy.window().then((window) => {
// Reference global instances set in "src/mocks/browser.js".
const { worker, rest } = window.msw;
const { worker, http } = window.msw;

worker.use(
rest.get('/records/count', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(2500)); //arbirary number greater than 1000
})
http.get('/records/count', () =>
HttpResponse.json(2500, { status: 200 })
)
);
});

Expand Down
52 changes: 30 additions & 22 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,13 @@ Cypress.Commands.add('startSnoopingBrowserMockedRequest', () => {
cy.window().then((window) => {
const worker = window?.msw?.worker;

worker.events.on('request:match', (req) => {
mockedRequests.push(req);
// Use start here instead of match as needs to be done before the request is read to
// avoid errors as an MDN Request's contents can only be read once. We then clone it
// here to ensure the MSW handlers can call .json() on it, and also any Cypress tests
// which would otherwise have failed for the same reason as json() can only be called
// once on the original request.
worker.events.on('request:start', ({ request }) => {
mockedRequests.push(request.clone());
});
});
});
Expand All @@ -103,27 +108,30 @@ Cypress.Commands.add('startSnoopingBrowserMockedRequest', () => {
*/
Cypress.Commands.add('findBrowserMockedRequests', ({ method, url }) => {
return cy.window().then((window) => {
const { matchRequestUrl } = window?.msw;
const msw = window?.msw;
if (msw) {
const { matchRequestUrl } = msw;

return new Cypress.Promise((resolve, reject) => {
if (
!method ||
!url ||
typeof method !== 'string' ||
typeof url !== 'string'
) {
return reject(
`Invalid parameters passed. Method: ${method} Url: ${url}`
return new Cypress.Promise((resolve, reject) => {
if (
!method ||
!url ||
typeof method !== 'string' ||
typeof url !== 'string'
) {
return reject(
`Invalid parameters passed. Method: ${method} Url: ${url}`
);
}
resolve(
mockedRequests.filter((req) => {
const matchesMethod =
req.method && req.method.toLowerCase() === method.toLowerCase();
const matchesUrl = matchRequestUrl(new URL(req.url), url).matches;
return matchesMethod && matchesUrl;
})
);
}
resolve(
mockedRequests.filter((req) => {
const matchesMethod =
req.method && req.method.toLowerCase() === method.toLowerCase();
const matchesUrl = matchRequestUrl(req.url, url).matches;
return matchesMethod && matchesUrl;
})
);
});
});
}
});
});
2 changes: 0 additions & 2 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ import './util';

// Alternatively you can use CommonJS syntax:
// require('./commands')

require('cypress-failed-log');
Loading

0 comments on commit 1ce6e85

Please sign in to comment.