Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,65 @@ on:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

permissions:
contents: read
pull-requests: read

jobs:
test:
detect-push-pr-association:
if: github.event_name == 'push'
runs-on: ubuntu-latest
outputs:
has_pr: ${{ steps.detect.outputs.has_pr }}
steps:
- name: Detect whether pushed commit belongs to a PR
id: detect
uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const commitSha = context.sha;
const response = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner,
repo,
commit_sha: commitSha,
});
core.setOutput('has_pr', response.data.length > 0 ? 'true' : 'false');

pr-all-browsers:
if: github.event_name == 'pull_request'
strategy:
fail-fast: false
matrix:
react-major: [16, 17, 18, 19]
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run all browser Playwright tests (React ${{ matrix.react-major }})
run: npm run test:with-react -- ${{ matrix.react-major }} all-browsers
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-pr-react-${{ matrix.react-major }}-all-browsers
path: playwright-report/
retention-days: 30

push-react-matrix:
if: github.event_name == 'push' && needs.detect-push-pr-association.outputs.has_pr != 'true'
needs: detect-push-pr-association
Comment on lines +59 to +61
strategy:
fail-fast: false
matrix:
react-major: [16, 17, 18, 19]
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
Expand All @@ -17,11 +74,11 @@ jobs:
run: npm ci --legacy-peer-deps
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npm run test
- name: Run all browser Playwright tests (React ${{ matrix.react-major }})
run: npm run test:with-react -- ${{ matrix.react-major }} all-browsers
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
name: playwright-report-push-react-${{ matrix.react-major }}-all-browsers
path: playwright-report/
retention-days: 30
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,29 @@ Uniquely formats while inputting, including decimal and thousands separators, pr
# Changes since the original

- Now in TypeScript
- Supports React 17, 18
- Supports React 16, 17, 18, 19
- Totally new automated testing setup with ~~Cypress~~ Playwright (new in 1.4.2+)
- Automated Testing setup much more thorough
- Caret selection redone and seems to work everywhere
- Uses react-device-detect to workaround issues with Gboard

## Testing Across React Versions

This package can be tested against React 16 through 19 locally:

```bash
npm run test:react16
npm run test:react17
npm run test:react18
npm run test:react19
```

Run all of them in sequence:

```bash
npm run test:matrix
```

## Codepen Demonstrations

There is a CodePen available which you may use to see the component in action, and play with all of it's various parameters to see how it works. It is written with React and TypeScript.
Expand Down
16 changes: 13 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@
"build:esm": "tsc --module es2015 --target es5 --outDir dist/esm",
"build:cjs": "tsc --module commonjs --target es5 --outDir dist/cjs",
"build-example": "npm run build && browserify examples/index.js -o examples/bundle.js -t [ babelify --presets [ @babel/preset-env ] ]",
"test": "npm run build-example && npx playwright test",
"test": "npm run test:compat",
"test:compat": "npm run build-example && npx playwright test --project=\"base tests\" --project=chromium --reporter=line",
"test:all-browsers": "npm run build-example && npx playwright test --reporter=line",
Comment on lines +16 to +18
"test:with-react": "node scripts/test-react-version.cjs",
"test:with-react:all-browsers": "node scripts/test-react-version.cjs",
"test:react16": "npm run test:with-react -- 16",
"test:react17": "npm run test:with-react -- 17",
"test:react18": "npm run test:with-react -- 18",
"test:react19": "npm run test:with-react -- 19",
"test:matrix": "npm run test:react16 && npm run test:react17 && npm run test:react18 && npm run test:react19",
"test:matrix:all-browsers": "npm run test:with-react -- 16 all-browsers && npm run test:with-react -- 17 all-browsers && npm run test:with-react -- 18 all-browsers && npm run test:with-react -- 19 all-browsers",
"upgrade-deps": "npx npm-check-updates --doctor -u --peer",
"webpack": "webpack",
"webpack-dev": "webpack-dev-server"
Expand Down Expand Up @@ -41,8 +51,8 @@
},
"homepage": "https://github.com/ericblade/react-currency-input#readme",
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react": ">=16.14.0 <20",
"react-dom": ">=16.14.0 <20"
},
"devDependencies": {
"@babel/preset-env": "^7.24.8",
Expand Down
95 changes: 95 additions & 0 deletions scripts/test-react-version.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const { spawnSync } = require('node:child_process');
const fs = require('node:fs');
const path = require('node:path');

const reactMajor = process.argv[2];
const mode = process.argv[3] || 'compat';
const supportedMajors = new Set(['16', '17', '18', '19']);
const modeToTestScript = {
compat: 'test:compat',
'all-browsers': 'test:all-browsers',
};

if (!supportedMajors.has(reactMajor)) {
console.error('Usage: npm run test:with-react -- <16|17|18|19> [compat|all-browsers]');
process.exit(1);
}

if (!modeToTestScript[mode]) {
console.error('Mode must be one of: compat, all-browsers');
process.exit(1);
}

function run(command, args) {
const result = spawnSync(command, args, {
stdio: 'inherit',
shell: process.platform === 'win32',
});

if (result.status !== 0) {
process.exit(result.status || 1);
}
}

function ensureReactDomClientShimForLegacy(major) {
if (major !== '16' && major !== '17') {
return;
}

const shimPath = path.join(process.cwd(), 'node_modules', 'react-dom', 'client.js');
const shimSource = `const ReactDOM = require('./index.js');\n\nexports.createRoot = function createRoot(container) {\n return {\n render(element) {\n ReactDOM.render(element, container);\n },\n unmount() {\n ReactDOM.unmountComponentAtNode(container);\n },\n };\n};\n`;

fs.writeFileSync(shimPath, shimSource, 'utf8');
}

const versionMatrix = {
'16': {
react: '^16.14.0',
reactDom: '^16.14.0',
typesReact: '^16.14.0',
typesReactDom: '^16.9.0',
},
'17': {
react: '^17.0.2',
reactDom: '^17.0.2',
typesReact: '^17.0.0',
typesReactDom: '^17.0.0',
},
'18': {
react: '^18.2.0',
reactDom: '^18.2.0',
typesReact: '^18.0.0',
typesReactDom: '^18.0.0',
},
'19': {
react: '^19.0.0',
reactDom: '^19.0.0',
typesReact: '^19.0.0',
typesReactDom: '^19.0.0',
},
};

const selected = versionMatrix[reactMajor];
const packageSpecs = [
`react@${selected.react}`,
`react-dom@${selected.reactDom}`,
`@types/react@${selected.typesReact}`,
`@types/react-dom@${selected.typesReactDom}`,
'@types/scheduler@^0.16.8',
];

console.log(`Installing React ${reactMajor}.x test deps...`);
run('npm', ['install', '--no-save', '--no-package-lock', '--legacy-peer-deps', ...packageSpecs]);

ensureReactDomClientShimForLegacy(reactMajor);

if (mode === 'all-browsers') {
console.log('Ensuring all Playwright browsers are installed...');
run('npx', ['playwright', 'install']);
} else {
console.log('Ensuring Playwright Chromium is installed...');
run('npx', ['playwright', 'install', 'chromium']);
}

console.log(`Running ${modeToTestScript[mode]} with React ${reactMajor}.x...`);
run('npm', ['run', modeToTestScript[mode]]);
Loading