Installations
npm install @smartive/xstate-test-toolbox
Developer Guide
Typescript
Yes
Module System
CommonJS
Min. Node Version
^22.0.0
Node Version
18.20.5
NPM Version
10.8.2
Score
68.3
Supply Chain
98.7
Quality
82.8
Maintenance
100
Vulnerability
100
License
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (100%)
Developer
Download Statistics
Total Downloads
7,186
Last Day
1
Last Week
20
Last Month
45
Last Year
506
GitHub Statistics
13 Stars
324 Commits
6 Watching
12 Branches
5 Contributors
Bundle Size
14.59 kB
Minified
5.02 kB
Minified + Gzipped
Package Meta Information
Latest Version
2.0.10
Package Id
@smartive/xstate-test-toolbox@2.0.10
Unpacked Size
14.23 kB
Size
4.90 kB
File Count
5
NPM Version
10.8.2
Node Version
18.20.5
Publised On
23 Nov 2024
Total Downloads
Cumulative downloads
Total Downloads
7,186
Last day
-80%
1
Compared to previous day
Last week
150%
20
Compared to previous week
Last month
150%
45
Compared to previous month
Last year
-82.7%
506
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
@smartive/xstate-test-toolbox
This package contains the helper createTestPlans
which can be used with xstate and @xstate/test.
createTestPlans
This function adds the meta
-property to every state and a test if it is defined within tests
. (see in example) Beside that it generates all possible test simple path plans for all possible combinations of your guards.
⚠️ Attention: Your statechart must consist of only string references to guards, actions and services otherwise the testing will break.
Example
1// The following snippet does not include all needed imports and code it is intended 2// to give you a starting point and an idea how the `createTestPlans`-function can be used. 3 4import { createTestPlans, StatesTestFunctions } from '@smartive/xstate-test-toolbox'; 5import { FetchInterceptor, mockHeaders, mockResponse, RequestCallCountMock } from '@smartive/testcafe-utils'; 6import { TestEventsConfig } from '@xstate/test/lib/types'; 7import { RequestMock } from 'testcafe'; 8import { Context, machine } from './machine-under-test'; 9// ... 10 11type TestContext = { 12 t: TestController, 13 plan: string, 14 path: string 15}; 16 17const fetchInterceptor = new FetchInterceptor({ 18 fetchPeople: /.+swapi\.dev.+\/people\/$/, 19 fetchMore: /.+swapi\.dev.+\/people\/\?page=.+/, 20 searchPeople: /.+swapi\.dev.+\/people\/\?search=.+/, 21}); 22 23const getRequestMocks = (plan: string, path: string): object[] => { 24 const peopleUrl = /.+swapi\.dev.+\/people\/.*/ 25 if ( 26 plan.includes('NoResults') || 27 (plan.includes('Searching') && path.includes('NoResults')) 28 ) { 29 return [ 30 RequestMock() 31 .onRequestTo(peopleUrl) 32 .respond(empty, 200, mockHeaders), 33 ]; 34 } 35 36 if (plan.includes('Error')) { 37 switch (path) { 38 case 'Pending → error.platform.fetchPeople': 39 return [ 40 RequestMock().onRequestTo(peopleUrl).respond({}, 400, mockHeaders), 41 ]; 42 case 'Pending → done.invoke.fetchPeople → Idle → END_REACHED → LoadingMore → error.platform.fetchMore': 43 return [ 44 new RequestCallCountMock(peopleUrl, [ 45 { body: mockResponse(peoples) }, 46 { body: mockResponse({}, 400) }, 47 ]), 48 ]; 49 case 'Pending → done.invoke.fetchPeople → NoResults → QUERY_DISPATCHED → Searching → error.platform.searchPeople': 50 return [ 51 RequestMock() 52 .onRequestTo(fetchInterceptor.interceptUrls.searchPeople) 53 .respond({}, 400, mockHeaders), 54 RequestMock() 55 .onRequestTo(peopleUrl) 56 .respond(empty, 200, mockHeaders), 57 ]; 58 case 'Pending → done.invoke.fetchPeople → Idle → QUERY_DISPATCHED → Searching → error.platform.searchPeople': 59 return [ 60 RequestMock() 61 .onRequestTo(fetchInterceptor.interceptUrls.searchPeople) 62 .respond({}, 400, mockHeaders), 63 ]; 64 } 65 } 66 67 return []; 68}; 69 70const tests: StatesTestFunctions<Context, TestContext> = { 71 Pending: ({ t }) => t.expect(page.spinner.exists).ok(), 72 Idle: ({ t }) => t.expect(page.listItem.count).gt(0), 73 LoadingMore: ({ t }) => t.expect(page.listItem.count).gt(1).expect(page.spinner.exists).ok(), 74 Error: ({ t }) => t.expect(page.error.exists).ok(), 75 NoResults: ({ t }) => t.expect(page.notify.exists).ok(), 76 Searching: ({ t }) => t.expect(page.search.value).contains('luke').expect(page.spinner.exists).ok(), 77}; 78 79const testEvents: TestEventsConfig<TestContext> = { 80 END_REACHED: ({ t }) => t.hover(page.listItem.nth(9), { speed: 0.8 }), 81 QUERY_DISPATCHED: ({ t }) => t.typeText(page.search, 'luke', { speed: 0.8 }), 82 'done.invoke.fetchPeople': fetchInterceptor.resolve('fetchPeople'), 83 'error.platform.fetchPeople': fetchInterceptor.resolve('fetchPeople'), 84 'error.platform.fetchMore': fetchInterceptor.resolve('fetchMore'), 85 'error.platform.searchPeople': fetchInterceptor.resolve('searchPeople'), 86}; 87 88createTestPlans({ 89 machine, 90 tests, 91 testEvents, 92 // add logLevel: LogLevel.INFO for some output which plans/paths are generated 93}).forEach( 94 ({ description: plan, paths }) => { 95 fixture(plan).page(`http://localhost:3000/peoples`); 96 97 paths.forEach(({ test: run, description: path }) => { 98 test 99 .clientScripts([fetchInterceptor.clientScript()]) 100 .requestHooks(getRequestMocks(plan, path))(`via ${path} ⬏`, (t) => run({ plan, path, t })); 101 }); 102 } 103);
No vulnerabilities found.
Reason
23 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
packaging workflow detected
Details
- Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:9
Reason
0 existing vulnerabilities detected
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/merge-request.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/smartive/xstate-test-toolbox/merge-request.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/merge-request.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/smartive/xstate-test-toolbox/merge-request.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/smartive/xstate-test-toolbox/release.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/smartive/xstate-test-toolbox/release.yml/main?enable=pin
- Info: 0 out of 4 GitHub-owned GitHubAction dependencies pinned
- Info: 2 out of 2 npmCommand dependencies pinned
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/merge-request.yml:1
- Warn: no topLevel permission defined: .github/workflows/release.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 30 are checked with a SAST tool
Score
5.4
/10
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More