Skip to content

Commit 6b9b277

Browse files
committed
feat: use vite testing
1 parent 67be98e commit 6b9b277

40 files changed

+731
-263
lines changed

Diff for: .github/workflows/ci.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ jobs:
3434
run: |
3535
echo "CYPRESS_RECORD_KEY=${{ secrets.CYPRESS_RECORD_KEY }}" >> $GITHUB_ENV
3636
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
37-
echo "CYPRESS_INSTALL_BINARY=6.0.0" >> $GITHUB_ENV
37+
echo "CYPRESS_INSTALL_BINARY=13.14.2" >> $GITHUB_ENV
3838
3939
- name: Checkout
4040
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
4141

4242
- name: Cypress run
43-
uses: cypress-io/github-action@v2
43+
uses: cypress-io/github-action@v4
4444
with:
4545
browser: ${{ matrix.browsers }}
4646
build: npm run build

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
# production
2121
/build
22+
/dist
2223

2324
# misc
2425
.DS_Store

Diff for: cypress-install.js

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
const util = require('cypress/lib/util');
2-
const execa = require('execa');
1+
import { spawn } from 'child_process';
32

4-
const pkg = util.pkgVersion();
3+
const child = spawn('npm', ['run', 'cypress:install'], {
4+
stdio: 'inherit'
5+
});
56

6-
(async () => {
7-
console.log('Installing Cypress ' + pkg);
8-
await execa('npm', ['run', 'cypress:install'], {
9-
env: { CYPRESS_INSTALL_BINARY: pkg }
10-
});
11-
console.log('Cypress installed');
12-
})();
7+
child.on('close', code => {
8+
if (code) {
9+
console.error('Cypress installation failed with code:', code);
10+
}
11+
});
12+
13+
child.on('error', error => {
14+
console.error('Cypress installation error:', error);
15+
});

Diff for: cypress.config.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const { defineConfig } = require('cypress');
2+
3+
module.exports = defineConfig({
4+
e2e: {
5+
baseUrl: 'http://localhost:3001',
6+
retries: 4
7+
}
8+
})

Diff for: cypress.json

-3
This file was deleted.
File renamed without changes.

Diff for: cypress/integration/play-button.js renamed to cypress/e2e/play-button.cy.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
describe('Stop and play the music', () => {
2-
beforeEach(() => {
3-
cy.visit('http://localhost:3001');
4-
});
2+
it('Click play button', function () {
53

6-
it('Click play button', () => {
4+
// Endless test trying to load the Discord integration
5+
// https://stackoverflow.com/questions/64673128/cypress-iframe-function-works-on-chrome-but-not-firefox
6+
if (Cypress.browser.name === 'firefox') {
7+
this.skip();
8+
}
9+
10+
cy.visit('http://localhost:3001');
711
cy.get('audio')
812
.invoke('attr', 'src')
913
.should('contain', '.mp3')

Diff for: cypress/plugins/index.js

-22
This file was deleted.
File renamed without changes.
File renamed without changes.

Diff for: cypress/tsconfig.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es6",
4+
"module": "esnext",
5+
"allowSyntheticDefaultImports": true,
6+
"sourceMap": true,
7+
"jsx": "preserve",
8+
"allowJs": false,
9+
"noImplicitAny": true,
10+
"moduleResolution": "node",
11+
"isolatedModules": true,
12+
"types": ["node","cypress"]
13+
},
14+
"include": [
15+
"**/*.ts",
16+
],
17+
}

Diff for: index.html

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
6+
<meta
7+
name="viewport"
8+
content="width=device-width, minimum-scale=1.0, maximum-scale=8.0"
9+
/>
10+
<meta content="X5tHeKjV-jMLyp4VMoUhW9PAYaOjtPslV250" name="csrf-token" />
11+
<link href="https://coderadio.freecodecamp.org" rel="canonical" />
12+
<meta
13+
content="Code Radio - 24/7 concentration music for developers"
14+
property="og:title"
15+
/>
16+
<meta content="freeCodeCamp.org" property="og:site_name" />
17+
<meta content="on" name="twitter:widgets:csp" />
18+
<meta content="d0bc047a482c03c24f1168004c2a216a" name="p:domain_verify" />
19+
<meta content="https://coderadio.freecodecamp.org" property="og:url" />
20+
<meta
21+
content="Code Radio - 24/7 concentration music for developers"
22+
property="og:description"
23+
/>
24+
<meta
25+
content="https://cdn.freecodecamp.org/coderadio/coderadio-meta-1920x1080.png"
26+
property="og:image"
27+
/>
28+
<meta content="article" property="og:type" />
29+
<meta
30+
content="https://www.facebook.com/freecodecamp"
31+
property="article:publisher"
32+
/>
33+
<meta content="Responsive" property="article:section" />
34+
<meta content="Support" name="description" />
35+
<meta content="@freecodecamp" name="twitter:creator" />
36+
<meta content="https://coderadio.freecodecamp.org" name="twitter:url" />
37+
<meta content="@freecodecamp" name="twitter:site" />
38+
<meta content="summary_large_image" name="twitter:card" />
39+
<meta
40+
content="https://cdn.freecodecamp.org/coderadio/coderadio-meta-1920x1080.png"
41+
name="twitter:image:src"
42+
/>
43+
<meta content="Code Radio" name="twitter:title" />
44+
<meta
45+
content="24/7 concentration music for developers"
46+
name="twitter:description"
47+
/>
48+
<meta content="a40ee5d5dba3bb091ad783ebd2b1383f" name="p:domain_verify" />
49+
<meta content="#FFFFFF" name="msapplication-TileColor" />
50+
<meta
51+
content="https://cdn.freecodecamp.org/universal/favicons/browserconfig.xml"
52+
rel="msapplication-config"
53+
/>
54+
<link
55+
href="https://cdn.freecodecamp.org/universal/favicons/android-chrome-192x192.png"
56+
rel="android-chrome"
57+
sizes="192x192"
58+
/>
59+
<link
60+
href="https://cdn.freecodecamp.org/universal/favicons/android-chrome-384x384.png"
61+
rel="android-chrome"
62+
sizes="384x384"
63+
/>
64+
<link
65+
href="https://cdn.freecodecamp.org/universal/favicons/site.webmanifest"
66+
rel="manifest"
67+
/>
68+
<link
69+
href="https://cdn.freecodecamp.org/universal/favicons/apple-touch-icon.png"
70+
rel="apple-touch-icon"
71+
sizes="180x180"
72+
/>
73+
<link
74+
href="https://cdn.freecodecamp.org/universal/favicons/favicon-16x16.png"
75+
rel="favicon"
76+
sizes="16x16"
77+
/>
78+
<link
79+
href="https://cdn.freecodecamp.org/universal/favicons/favicon-32x32.png"
80+
rel="favicon"
81+
sizes="32x32"
82+
/>
83+
<link
84+
href="https://cdn.freecodecamp.org/universal/favicons/favicon.ico"
85+
rel="icon"
86+
/>
87+
<title>freeCodeCamp.org Code Radio</title>
88+
<script
89+
async
90+
src="https://www.googletagmanager.com/gtag/js?id=UA-55446531-21"
91+
></script>
92+
<script>
93+
window.dataLayer = window.dataLayer || [];
94+
function gtag() {
95+
dataLayer.push(arguments);
96+
}
97+
gtag('js', new Date());
98+
gtag('config', 'UA-55446531-21');
99+
</script>
100+
</head>
101+
<body>
102+
<div id="app"></div>
103+
<script src="https://cdn.jsdelivr.net/npm/@widgetbot/crate@3" async defer>
104+
new Crate({
105+
server: '692816967895220344', // freeCodeCamp.org Official ᕕ(⌐■_■)ᕗ ♪♬
106+
channel: '1254842489362317322' // #code-radio
107+
})
108+
const button = document.querySelector('crate > div').shadowRoot.querySelector("button");
109+
button.style.bottom = "90px";
110+
const embed = document.querySelector('crate > div').shadowRoot.querySelector(".embed");
111+
embed.style.bottom = "90px";
112+
// we only need to adjust the height at the iframe's mobile breakpoint.
113+
// This does break during resizing, but I think that's enough of an edge case.
114+
if (window.innerWidth <= 500) {
115+
embed.style.maxHeight = "calc(100% - 80px)"
116+
}
117+
</script>
118+
<script type="module" src="/src/index.tsx"></script>
119+
</body>
120+
</html>

Diff for: package.json

+26-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "coderadio",
33
"version": "0.1.0",
44
"private": true,
5+
"type": "module",
56
"dependencies": {
67
"@fortawesome/fontawesome-svg-core": "6.6.0",
78
"@fortawesome/free-solid-svg-icons": "6.6.0",
@@ -11,16 +12,15 @@
1112
"react": "18.3.1",
1213
"react-device-detect": "2.2.3",
1314
"react-dom": "18.3.1",
14-
"react-page-visibility": "7.0.0",
15-
"react-scripts": "5.0.1",
16-
"store": "2.0.12"
15+
"react-page-visibility": "7.0.0"
1716
},
1817
"scripts": {
19-
"start": "PORT=3001 react-scripts start",
20-
"build": "react-scripts build",
21-
"test": "react-scripts test --watchAll=false",
22-
"test:watch": "react-scripts test",
23-
"eject": "react-scripts eject",
18+
"start": "vite",
19+
"build": "vite build",
20+
"test": "vitest",
21+
"test:watch": "vitest --watch",
22+
"test:coverage": "vitest --coverage .",
23+
"test:debug": "vitest --inspect-brk --runInBand --no-cache",
2424
"precypress": "node cypress-install.js",
2525
"cypress": "cypress",
2626
"cypress:open": "npm run cypress open",
@@ -42,15 +42,29 @@
4242
]
4343
},
4444
"devDependencies": {
45-
"@testing-library/jest-dom": "6.6.2",
45+
"@testing-library/jest-dom": "6.5.0",
4646
"@testing-library/react": "16.0.1",
47-
"cypress": "13.15.1",
47+
"@types/jest": "29.5.13",
48+
"@types/node": "22.5.4",
49+
"@types/react": "18.3.5",
50+
"@types/react-dom": "18.3.0",
51+
"@vitejs/plugin-react": "4.3.1",
52+
"cypress": "13.14.2",
4853
"eslint-config-prettier": "9.1.0",
4954
"eslint-plugin-prettier": "5.2.1",
50-
"execa": "9.5.1",
55+
"eventsource": "2.0.2",
56+
"eventsourcemock": "2.0.0",
57+
"happy-dom": "15.7.4",
5158
"husky": "9.1.6",
59+
"jest": "29.7.0",
60+
"jest-environment-jsdom": "29.7.0",
5261
"lint-staged": "15.2.10",
53-
"prettier": "3.3.3"
62+
"prettier": "3.3.3",
63+
"ts-jest": "29.2.5",
64+
"typescript": "5.6.2",
65+
"vite": "5.4.4",
66+
"vite-tsconfig-paths": "5.0.1",
67+
"vitest": "2.1.0"
5468
},
5569
"lint-staged": {
5670
"*.js": "npm run lint:fix"

Diff for: sample.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Sentry DSN - a public id that identifies your app to Sentry
2-
REACT_APP_SENTRY_DSN=<DSN-from-sentry-project-settings>
2+
VITE_SENTRY_DSN=<DSN-from-sentry-project-settings>

Diff for: src/assets/icons/pause.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
3+
function Pause(): JSX.Element {
4+
5+
return (<svg viewBox='0 0 640 640' fill='currentColor'>
6+
<title>Pause Button</title>
7+
<path d='M0 0L235.67 0L235.67 640L0 640L0 0Z' />
8+
<path d='M404.33 0L640 0L640 640L404.33 640L404.33 0Z' />
9+
</svg>
10+
);
11+
}
12+
13+
14+
Pause.displayName = 'Caret';
15+
export default Pause;

Diff for: src/assets/icons/play.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
3+
function Play(): JSX.Element {
4+
5+
return (
6+
<svg viewBox='0 0 640 640' fill='#fff'>
7+
<title>Play Button</title>
8+
<path d='M0 0L649.1 320L0 640L0 0Z' />
9+
</svg>
10+
);
11+
}
12+
13+
Play.displayName = 'Play';
14+
export default Play;

Diff for: src/assets/pause.svg

-5
This file was deleted.

Diff for: src/assets/play.svg

-4
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from 'react';
2-
import ReactDOM from 'react-dom';
32
import App from './App';
3+
import { createRoot } from 'react-dom/client';
44

55
it('renders without crashing', () => {
66
const div = document.createElement('div');
7-
ReactDOM.render(<App />, div);
8-
ReactDOM.unmountComponentAtNode(div);
7+
const root = createRoot(div!);
8+
root.render(<App />);
99
});

0 commit comments

Comments
 (0)