{"id":17917,"library":"redux-waitfor-middleware","title":"Redux Waitfor Middleware","description":"Redux Waitfor Middleware (current stable version 1.0.1) is a lightweight utility designed to facilitate testing of Redux applications, particularly for asynchronous flows. It operates as a standard Redux middleware, recording dispatched actions and providing a `waitFor` method that allows tests to pause execution until a specific set of actions has been dispatched within a given timeout. The library is primarily used in testing environments to assert on the sequence and payload of actions after asynchronous operations complete, such as API calls. Its release cadence appears to be stable, with the current version being quite mature. A key differentiator is its simplicity and direct focus on action-based waiting, making it less verbose than complex mocking or promise-chaining in some test scenarios. It also handles the case where actions are already dispatched, immediately resolving the wait.","status":"active","version":"1.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/Polyconseil/redux-waitfor-middleware","tags":["javascript","redux","test","tests","middleware","record","waitfor","wait"],"install":[{"cmd":"npm install redux-waitfor-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add redux-waitfor-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-waitfor-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core Redux library required for middleware integration and store creation.","package":"redux","optional":false}],"imports":[{"note":"The library primarily uses a default export for the middleware factory. While CommonJS `require` might work in some transpiled environments, native ESM import is preferred.","wrong":"const createWaitForMiddleware = require('redux-waitfor-middleware');","symbol":"createWaitForMiddleware","correct":"import createWaitForMiddleware from 'redux-waitfor-middleware';"},{"note":"This is a method on the instance returned by `createWaitForMiddleware`, not a direct import.","symbol":"waitFor","correct":"const waitForMiddleware = createWaitForMiddleware();\nawait waitForMiddleware.waitFor(['ACTION_TYPE']);"},{"note":"This is a method on the instance returned by `createWaitForMiddleware`, essential for resetting recorded actions between tests.","symbol":"clean","correct":"waitForMiddleware.clean();"}],"quickstart":{"code":"import createWaitForMiddleware from 'redux-waitfor-middleware';\nimport { createStore, applyMiddleware } from 'redux';\n\n// A dummy reducer for demonstration\nconst exampleReducer = (state = { data: [] }, action) => {\n  switch (action.type) {\n    case 'FETCH_DATA_REQUEST':\n      return { ...state, loading: true };\n    case 'FETCH_DATA_SUCCESS':\n      return { ...state, loading: false, data: action.payload };\n    case 'FETCH_DATA_FAILURE':\n      return { ...state, loading: false, error: action.error };\n    default:\n      return state;\n  }\n};\n\nconst waitForMiddleware = createWaitForMiddleware();\nconst store = createStore(exampleReducer, applyMiddleware(waitForMiddleware));\n\nasync function simulateFetch() {\n  store.dispatch({ type: 'FETCH_DATA_REQUEST' });\n  console.log('Dispatched FETCH_DATA_REQUEST');\n\n  // Simulate an async operation\n  setTimeout(() => {\n    store.dispatch({ type: 'FETCH_DATA_SUCCESS', payload: ['item1', 'item2'] });\n    console.log('Dispatched FETCH_DATA_SUCCESS');\n  }, 100);\n}\n\nasync function runTest() {\n  console.log('Running test...');\n  simulateFetch();\n\n  try {\n    const successActions = await waitForMiddleware.waitFor(['FETCH_DATA_SUCCESS'], 500);\n    console.log('Test passed! Received actions:', successActions);\n    console.assert(successActions.length === 1, 'Expected one success action');\n    console.assert(successActions[0].payload.includes('item1'), 'Payload check');\n  } catch (error) {\n    console.error('Test failed:', error.message);\n  } finally {\n    // Always clean up after a test\n    waitForMiddleware.clean();\n    console.log('Cleaned recorded actions.');\n  }\n}\n\nrunTest();","lang":"javascript","description":"This quickstart demonstrates how to integrate `redux-waitfor-middleware` into a Redux store, simulate an asynchronous action flow, and then use `waitForMiddleware.waitFor()` to assert that a specific action ('FETCH_DATA_SUCCESS') is dispatched within a given timeout."},"warnings":[{"fix":"Always call `waitForMiddleware.clean()` at the beginning or end of each individual test case (e.g., in `beforeEach` or `afterEach` hooks) to ensure a fresh state for each test.","message":"Actions dispatched before the `waitFor` call but after the last `clean()` call will immediately resolve the `waitFor` promise. This can lead to flaky tests if `clean()` is not called consistently between test cases.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Wrap `await waitForMiddleware.waitFor(...)` calls in a `try...catch` block if you need to specifically handle timeout scenarios without failing the test, though typically, a timeout indicates a test failure.","message":"The `waitFor` method throws an `Error` if the specified actions are not dispatched within the provided timeout. This will fail the test by default and needs to be handled if non-receipt of an action is an expected test outcome.","severity":"breaking","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Verify that the actions are indeed dispatched by your application logic, increase the timeout value if the operation genuinely takes longer, or ensure that `clean()` isn't prematurely clearing an action you're waiting for from a prior test.","cause":"One or more of the specified action types were not dispatched within the allocated timeout period.","error":"Error: Timeout of XXXXms reached waiting for actions: ACTION_TYPE_A, ACTION_TYPE_B"},{"fix":"Ensure `const waitForMiddleware = createWaitForMiddleware();` is called and `waitForMiddleware` is accessible where you are attempting to use its methods. It's often passed around or made available via a setup function in testing frameworks.","cause":"The `waitForMiddleware` instance was not correctly created or is out of scope. The `createWaitForMiddleware` function returns an object with `waitFor` and `clean` methods.","error":"TypeError: Cannot read properties of undefined (reading 'waitFor')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}