gitextract_4jsmhnkg/ ├── .gitignore ├── LICENSE ├── README.md ├── chapter11/ │ ├── 1_writing_end_to_end_tests/ │ │ ├── 1_setting_up_cypress/ │ │ │ ├── cypress/ │ │ │ │ ├── fixtures/ │ │ │ │ │ └── example.json │ │ │ │ ├── integration/ │ │ │ │ │ └── examples/ │ │ │ │ │ ├── actions.spec.js │ │ │ │ │ ├── aliasing.spec.js │ │ │ │ │ ├── assertions.spec.js │ │ │ │ │ ├── connectors.spec.js │ │ │ │ │ ├── cookies.spec.js │ │ │ │ │ ├── cypress_api.spec.js │ │ │ │ │ ├── files.spec.js │ │ │ │ │ ├── local_storage.spec.js │ │ │ │ │ ├── location.spec.js │ │ │ │ │ ├── misc.spec.js │ │ │ │ │ ├── navigation.spec.js │ │ │ │ │ ├── network_requests.spec.js │ │ │ │ │ ├── querying.spec.js │ │ │ │ │ ├── spies_stubs_clocks.spec.js │ │ │ │ │ ├── traversal.spec.js │ │ │ │ │ ├── utilities.spec.js │ │ │ │ │ ├── viewport.spec.js │ │ │ │ │ ├── waiting.spec.js │ │ │ │ │ └── window.spec.js │ │ │ │ ├── plugins/ │ │ │ │ │ └── index.js │ │ │ │ └── support/ │ │ │ │ ├── commands.js │ │ │ │ └── index.js │ │ │ ├── cypress.json │ │ │ └── package.json │ │ ├── 2_writing_your_first_tests/ │ │ │ ├── cypress/ │ │ │ │ ├── dbConnection.js │ │ │ │ ├── fixtures/ │ │ │ │ │ └── example.json │ │ │ │ ├── integration/ │ │ │ │ │ └── itemSubmission.spec.js │ │ │ │ ├── knexfile.js │ │ │ │ ├── plugins/ │ │ │ │ │ ├── dbPlugin.js │ │ │ │ │ └── index.js │ │ │ │ └── support/ │ │ │ │ ├── commands.js │ │ │ │ └── index.js │ │ │ ├── cypress.json │ │ │ └── package.json │ │ └── 3_sending_http_requests/ │ │ ├── cypress/ │ │ │ ├── dbConnection.js │ │ │ ├── fixtures/ │ │ │ │ └── example.json │ │ │ ├── integration/ │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ └── itemSubmission.spec.js │ │ │ ├── knexfile.js │ │ │ ├── plugins/ │ │ │ │ ├── dbPlugin.js │ │ │ │ └── index.js │ │ │ └── support/ │ │ │ ├── commands.js │ │ │ └── index.js │ │ ├── cypress.json │ │ └── package.json │ ├── 2_best_practices_for_end_to_end_tests/ │ │ ├── 1_page_objects/ │ │ │ ├── cypress/ │ │ │ │ ├── dbConnection.js │ │ │ │ ├── fixtures/ │ │ │ │ │ └── example.json │ │ │ │ ├── integration/ │ │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ │ └── itemSubmission.spec.js │ │ │ │ ├── knexfile.js │ │ │ │ ├── pageObjects/ │ │ │ │ │ └── inventoryManagement.js │ │ │ │ ├── plugins/ │ │ │ │ │ ├── dbPlugin.js │ │ │ │ │ └── index.js │ │ │ │ └── support/ │ │ │ │ ├── commands.js │ │ │ │ └── index.js │ │ │ ├── cypress.json │ │ │ └── package.json │ │ └── 2_application_actions/ │ │ ├── cypress/ │ │ │ ├── dbConnection.js │ │ │ ├── fixtures/ │ │ │ │ └── example.json │ │ │ ├── integration/ │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ └── itemSubmission.spec.js │ │ │ ├── knexfile.js │ │ │ ├── pageObjects/ │ │ │ │ └── inventoryManagement.js │ │ │ ├── plugins/ │ │ │ │ ├── dbPlugin.js │ │ │ │ └── index.js │ │ │ └── support/ │ │ │ ├── commands.js │ │ │ └── index.js │ │ ├── cypress.json │ │ └── package.json │ ├── 3_dealing_with_flakiness/ │ │ ├── 1_avoiding_waiting_for_fixed_amounts_of_time/ │ │ │ ├── cypress/ │ │ │ │ ├── dbConnection.js │ │ │ │ ├── fixtures/ │ │ │ │ │ └── example.json │ │ │ │ ├── integration/ │ │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ │ └── itemSubmission.spec.js │ │ │ │ ├── knexfile.js │ │ │ │ ├── pageObjects/ │ │ │ │ │ └── inventoryManagement.js │ │ │ │ ├── plugins/ │ │ │ │ │ ├── dbPlugin.js │ │ │ │ │ └── index.js │ │ │ │ └── support/ │ │ │ │ ├── commands.js │ │ │ │ └── index.js │ │ │ ├── cypress.json │ │ │ └── package.json │ │ └── 2_stubbing_uncontrollable_factors/ │ │ ├── cypress/ │ │ │ ├── dbConnection.js │ │ │ ├── fixtures/ │ │ │ │ └── example.json │ │ │ ├── integration/ │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ └── itemSubmission.spec.js │ │ │ ├── knexfile.js │ │ │ ├── pageObjects/ │ │ │ │ └── inventoryManagement.js │ │ │ ├── plugins/ │ │ │ │ ├── dbPlugin.js │ │ │ │ └── index.js │ │ │ └── support/ │ │ │ ├── commands.js │ │ │ └── index.js │ │ ├── cypress.json │ │ └── package.json │ ├── 4_visual_regression_tests/ │ │ ├── cypress/ │ │ │ ├── dbConnection.js │ │ │ ├── fixtures/ │ │ │ │ └── example.json │ │ │ ├── integration/ │ │ │ │ ├── itemList.spec.js │ │ │ │ ├── itemListUpdates.spec.js │ │ │ │ └── itemSubmission.spec.js │ │ │ ├── knexfile.js │ │ │ ├── pageObjects/ │ │ │ │ └── inventoryManagement.js │ │ │ ├── plugins/ │ │ │ │ ├── dbPlugin.js │ │ │ │ └── index.js │ │ │ └── support/ │ │ │ ├── commands.js │ │ │ └── index.js │ │ ├── cypress.json │ │ └── package.json │ ├── client/ │ │ ├── domController.js │ │ ├── domController.test.js │ │ ├── index.html │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── main.test.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ ├── setupJestDom.js │ │ ├── socket.js │ │ ├── socket.test.js │ │ ├── testSocketServer.js │ │ └── testUtils.js │ └── server/ │ ├── README.md │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ ├── 20200325082401_initial_schema.js │ │ └── 20200331210311_updatedAt_field.js │ ├── package.json │ ├── seedUser.js │ ├── seeds/ │ │ └── initial_inventory.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter13/ │ └── 1_type_systems/ │ ├── 1_no_types/ │ │ ├── orderQueue.js │ │ ├── orderQueue.spec.js │ │ └── package.json │ └── 2_with_types/ │ ├── orderQueue.js │ ├── orderQueue.spec.js │ ├── orderQueue.spec.ts │ ├── orderQueue.ts │ ├── package.json │ └── tsconfig.json ├── chapter2/ │ ├── 2_unit_tests/ │ │ ├── 1_raw_tests/ │ │ │ ├── Cart.js │ │ │ └── Cart.test.js │ │ ├── 2_node_assert/ │ │ │ ├── Cart.js │ │ │ └── Cart.test.js │ │ ├── 3_jest_multiple_tests/ │ │ │ ├── Cart.js │ │ │ ├── Cart.test.js │ │ │ └── package.json │ │ ├── 4_jest_assertions/ │ │ │ ├── Cart.js │ │ │ ├── Cart.test.js │ │ │ └── package.json │ │ └── 5_npm_scripts/ │ │ ├── Cart.js │ │ ├── Cart.test.js │ │ └── package.json │ ├── 3_integration_tests/ │ │ ├── 1_knex_tests_promise/ │ │ │ ├── cart.js │ │ │ ├── cart.test.js │ │ │ ├── dbConnection.js │ │ │ ├── knexfile.js │ │ │ ├── migrations/ │ │ │ │ └── 20191230210750_create_carts.js │ │ │ └── package.json │ │ ├── 2_knex_tests_done_cb/ │ │ │ ├── cart.js │ │ │ ├── cart.test.js │ │ │ ├── dbConnection.js │ │ │ ├── knexfile.js │ │ │ ├── migrations/ │ │ │ │ └── 20191230210750_create_carts.js │ │ │ └── package.json │ │ └── 3_knex_tests_hooks/ │ │ ├── cart.js │ │ ├── cart.test.js │ │ ├── dbConnection.js │ │ ├── knexfile.js │ │ ├── migrations/ │ │ │ └── 20191230210750_create_carts.js │ │ └── package.json │ ├── 4_end_to_end_tests/ │ │ ├── 1_http_api_tests/ │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ └── 2_http_api_with_remove_item/ │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ └── 5_tests_cost_and_revenue/ │ ├── 1_good_vs_bad/ │ │ ├── badly_written.test.js │ │ ├── package.json │ │ ├── server.js │ │ └── well_written.test.js │ └── 2_test_coupling/ │ ├── package.json │ ├── pow.test.js │ ├── pow_loop.js │ └── pow_recursive.js ├── chapter3/ │ ├── 1_organising_test_suites/ │ │ ├── 1_breaking_down_tests_big_tests/ │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ ├── 2_breaking_down_tests_small_tests/ │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ └── 3_global_hooks/ │ │ ├── dummy.test.js │ │ ├── globalSetup.js │ │ ├── globalTeardown.js │ │ ├── jest.config.js │ │ └── package.json │ ├── 2_writing_good_assertions/ │ │ ├── 1_assertion_checks/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ └── package.json │ │ ├── 2_assertion_checks_toThrow/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ └── package.json │ │ ├── 3_loose_assertions/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ └── package.json │ │ ├── 4_asymmetric_matchers/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ └── package.json │ │ ├── 5_manual_assertions/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ └── package.json │ │ ├── 6_custom_matchers/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── jest.config.js │ │ │ └── package.json │ │ └── 7_circular_assertions/ │ │ ├── inventoryController.js │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ ├── 3_mocks_stubs_and_spies/ │ │ ├── 1_mocking_objects/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── logger.js │ │ │ └── package.json │ │ ├── 2_mocking_imports/ │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── logger.js │ │ │ └── package.json │ │ └── 3_manual_mocks/ │ │ ├── __mocks__/ │ │ │ └── logger.js │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── logger.js │ │ └── package.json │ └── 4_code_coverage/ │ ├── 1_measuring_code_coverage/ │ │ ├── __mocks__/ │ │ │ └── logger.js │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── logger.js │ │ └── package.json │ └── 2_what_coverage_is_good_for/ │ ├── math.js │ ├── math.test.js │ └── package.json ├── chapter4/ │ ├── 1_setting_up_a_test_environment/ │ │ └── 1_exposing_modules/ │ │ ├── 1_end_to_end_tests/ │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ ├── 2_integration_tests/ │ │ │ ├── cartController.js │ │ │ ├── cartController.test.js │ │ │ ├── inventoryController.js │ │ │ ├── logger.js │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ └── 3_unit_tests/ │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── inventoryController.js │ │ ├── logger.js │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ ├── 2_testing_http_endpoints/ │ │ ├── 1_using_supertest/ │ │ │ ├── cartController.js │ │ │ ├── cartController.test.js │ │ │ ├── inventoryController.js │ │ │ ├── logger.js │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ └── server.test.js │ │ └── 2_testing_middlewares/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── inventoryController.js │ │ ├── logger.js │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ └── 3_dealing_with_external_dependencies/ │ ├── 1_database_integrations/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── inventoryController.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrations/ │ │ │ └── 20200325082401_initial_schema.js │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ ├── 2_separate_database_instances/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── inventoryController.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrations/ │ │ │ └── 20200325082401_initial_schema.js │ │ ├── package.json │ │ ├── server.js │ │ └── server.test.js │ ├── 3_maitaining_a_pristine_state/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── disconnectFromDb.js │ │ ├── inventoryController.js │ │ ├── jest.config.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrateDatabases.js │ │ ├── migrations/ │ │ │ └── 20200325082401_initial_schema.js │ │ ├── package.json │ │ ├── seedUser.js │ │ ├── server.js │ │ ├── server.test.js │ │ ├── truncateTables.js │ │ └── userTestUtils.js │ ├── 4_integrations_with_other_apis/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── disconnectFromDb.js │ │ ├── inventoryController.js │ │ ├── jest.config.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrateDatabases.js │ │ ├── migrations/ │ │ │ └── 20200325082401_initial_schema.js │ │ ├── package.json │ │ ├── seedUser.js │ │ ├── server.js │ │ ├── server.test.js │ │ ├── truncateTables.js │ │ └── userTestUtils.js │ ├── 5_using_mocks_to_avoid_requests/ │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── disconnectFromDb.js │ │ ├── inventoryController.js │ │ ├── jest.config.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrateDatabases.js │ │ ├── migrations/ │ │ │ └── 20200325082401_initial_schema.js │ │ ├── package.json │ │ ├── seedUser.js │ │ ├── server.js │ │ ├── server.test.js │ │ ├── truncateTables.js │ │ └── userTestUtils.js │ └── 6_using_nock_to_avoid_requests/ │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ └── 20200325082401_initial_schema.js │ ├── package.json │ ├── seedUser.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter5/ │ └── 1_eliminating_non_determinism/ │ ├── 1_shared_resources/ │ │ ├── countModule.js │ │ ├── decrement.test.js │ │ ├── increment.test.js │ │ └── package.json │ ├── 2_resource_pools/ │ │ ├── countModule.js │ │ ├── decrement.test.js │ │ ├── increment.test.js │ │ ├── instancePool.js │ │ └── package.json │ └── 3_dealing_with_time/ │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ ├── 20200325082401_initial_schema.js │ │ └── 20200331210311_updatedAt_field.js │ ├── package.json │ ├── seedUser.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter6/ │ ├── 1_introducing_jsdom/ │ │ ├── 1_pure_html/ │ │ │ ├── index.html │ │ │ └── main.js │ │ ├── 2_jsdom/ │ │ │ ├── example.js │ │ │ ├── index.html │ │ │ ├── main.js │ │ │ ├── package.json │ │ │ └── page.js │ │ └── 3_jest_jsdom/ │ │ ├── index.html │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── main.test.js │ │ └── package.json │ ├── 2_asserting_on_the_dom/ │ │ ├── 1_finding_elements_by_dom_structure/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── main.js │ │ │ └── package.json │ │ ├── 2_finding_elements_by_id/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── main.js │ │ │ └── package.json │ │ ├── 3_robust_element_queries/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── main.js │ │ │ └── package.json │ │ ├── 4_finding_with_dom_testing_library/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── main.js │ │ │ └── package.json │ │ └── 5_writing_better_dom_assertions/ │ │ ├── domController.js │ │ ├── domController.test.js │ │ ├── index.html │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── package.json │ │ └── setupJestDom.js │ ├── 3_handling_events/ │ │ ├── 1_handling_raw_events/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── jest.config.js │ │ │ ├── main.js │ │ │ ├── main.test.js │ │ │ ├── package.json │ │ │ └── setupJestDom.js │ │ ├── 2_bubbling_up_events/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── jest.config.js │ │ │ ├── main.js │ │ │ ├── main.test.js │ │ │ ├── package.json │ │ │ └── setupJestDom.js │ │ └── 3_dom_testing_library_events/ │ │ ├── domController.js │ │ ├── domController.test.js │ │ ├── index.html │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── main.test.js │ │ ├── package.json │ │ └── setupJestDom.js │ ├── 4_testing_and_browser_apis/ │ │ ├── 1_localstorage/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── jest.config.js │ │ │ ├── main.js │ │ │ ├── main.test.js │ │ │ ├── package.json │ │ │ └── setupJestDom.js │ │ ├── 2_history_api/ │ │ │ ├── domController.js │ │ │ ├── domController.test.js │ │ │ ├── index.html │ │ │ ├── inventoryController.js │ │ │ ├── inventoryController.test.js │ │ │ ├── jest.config.js │ │ │ ├── main.js │ │ │ ├── main.test.js │ │ │ ├── package.json │ │ │ ├── setupJestDom.js │ │ │ └── testUtils.js │ │ └── server/ │ │ ├── README.md │ │ ├── authenticationController.js │ │ ├── authenticationController.test.js │ │ ├── cartController.js │ │ ├── cartController.test.js │ │ ├── dbConnection.js │ │ ├── disconnectFromDb.js │ │ ├── inventoryController.js │ │ ├── jest.config.js │ │ ├── knexfile.js │ │ ├── logger.js │ │ ├── migrateDatabases.js │ │ ├── migrations/ │ │ │ ├── 20200325082401_initial_schema.js │ │ │ └── 20200331210311_updatedAt_field.js │ │ ├── package.json │ │ ├── seedUser.js │ │ ├── seeds/ │ │ │ └── initial_inventory.js │ │ ├── server.js │ │ ├── server.test.js │ │ ├── truncateTables.js │ │ └── userTestUtils.js │ └── 5_web_sockets_and_http_requests/ │ ├── 1_http_requests/ │ │ ├── domController.js │ │ ├── domController.test.js │ │ ├── index.html │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── main.test.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ ├── setupJestDom.js │ │ └── testUtils.js │ ├── 2_web_sockets/ │ │ ├── domController.js │ │ ├── domController.test.js │ │ ├── index.html │ │ ├── inventoryController.js │ │ ├── inventoryController.test.js │ │ ├── jest.config.js │ │ ├── main.js │ │ ├── main.test.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ ├── setupJestDom.js │ │ ├── socket.js │ │ ├── socket.test.js │ │ ├── testSocketServer.js │ │ └── testUtils.js │ └── server/ │ ├── README.md │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ ├── 20200325082401_initial_schema.js │ │ └── 20200331210311_updatedAt_field.js │ ├── package.json │ ├── seedUser.js │ ├── seeds/ │ │ └── initial_inventory.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter7/ │ ├── 1_setting_up_a_test_environment/ │ │ ├── 1_createElement_calls/ │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── 2_transforming_jsx/ │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ └── package.json │ │ └── 3_setting_up_jest/ │ │ ├── App.jsx │ │ ├── app.test.js │ │ ├── babel.config.js │ │ ├── index.html │ │ ├── index.jsx │ │ ├── jest.config.js │ │ └── package.json │ ├── 2_an_overview_of_react_testing_libraries/ │ │ ├── 1_react_testing_utilities/ │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── babel.config.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ └── setupJestDom.js │ │ └── 2_react_testing_library/ │ │ ├── App.jsx │ │ ├── App.test.jsx │ │ ├── ItemForm.jsx │ │ ├── ItemForm.test.jsx │ │ ├── ItemList.jsx │ │ ├── ItemList.test.jsx │ │ ├── babel.config.js │ │ ├── constants.js │ │ ├── index.html │ │ ├── index.jsx │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ └── setupJestDom.js │ └── server/ │ ├── README.md │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ ├── 20200325082401_initial_schema.js │ │ └── 20200331210311_updatedAt_field.js │ ├── package.json │ ├── seedUser.js │ ├── seeds/ │ │ └── initial_inventory.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter8/ │ ├── 1_testing_component_interaction/ │ │ ├── 1_component_integration_tests/ │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── ItemForm.jsx │ │ │ ├── ItemForm.test.jsx │ │ │ ├── ItemList.jsx │ │ │ ├── ItemList.test.jsx │ │ │ ├── babel.config.js │ │ │ ├── constants.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── setupGlobalFetch.js │ │ │ └── setupJestDom.js │ │ └── 2_stubbing_components/ │ │ ├── App.jsx │ │ ├── App.test.jsx │ │ ├── ItemForm.jsx │ │ ├── ItemForm.test.jsx │ │ ├── ItemList.jsx │ │ ├── ItemList.test.jsx │ │ ├── __mocks__/ │ │ │ └── react-spring/ │ │ │ └── renderprops.jsx │ │ ├── babel.config.js │ │ ├── constants.js │ │ ├── index.html │ │ ├── index.jsx │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ └── setupJestDom.js │ ├── 2_snapshot_testing/ │ │ ├── 1_component_snapshots/ │ │ │ ├── ActionLog.jsx │ │ │ ├── ActionLog.test.jsx │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── ItemForm.jsx │ │ │ ├── ItemForm.test.jsx │ │ │ ├── ItemList.jsx │ │ │ ├── ItemList.test.jsx │ │ │ ├── __mocks__/ │ │ │ │ └── react-spring/ │ │ │ │ └── renderprops.jsx │ │ │ ├── __snapshots__/ │ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ │ └── App.test.jsx.snap │ │ │ ├── babel.config.js │ │ │ ├── constants.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── setupGlobalFetch.js │ │ │ └── setupJestDom.js │ │ └── 2_snapshots_beyond_components/ │ │ ├── __snapshots__/ │ │ │ └── generate_report.test.js.snap │ │ ├── generate_report.js │ │ ├── generate_report.test.js │ │ └── package.json │ ├── 3_testing_styles/ │ │ ├── 1_css_classes/ │ │ │ ├── ActionLog.jsx │ │ │ ├── ActionLog.test.jsx │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── ItemForm.jsx │ │ │ ├── ItemForm.test.jsx │ │ │ ├── ItemList.jsx │ │ │ ├── ItemList.test.jsx │ │ │ ├── __mocks__/ │ │ │ │ └── react-spring/ │ │ │ │ └── renderprops.jsx │ │ │ ├── __snapshots__/ │ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ │ └── App.test.jsx.snap │ │ │ ├── babel.config.js │ │ │ ├── constants.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── setupGlobalFetch.js │ │ │ ├── setupJestDom.js │ │ │ └── styles.css │ │ ├── 2_style_props/ │ │ │ ├── ActionLog.jsx │ │ │ ├── ActionLog.test.jsx │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── ItemForm.jsx │ │ │ ├── ItemForm.test.jsx │ │ │ ├── ItemList.jsx │ │ │ ├── ItemList.test.jsx │ │ │ ├── __mocks__/ │ │ │ │ └── react-spring/ │ │ │ │ └── renderprops.jsx │ │ │ ├── __snapshots__/ │ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ │ └── App.test.jsx.snap │ │ │ ├── babel.config.js │ │ │ ├── constants.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── setupGlobalFetch.js │ │ │ ├── setupJestDom.js │ │ │ └── styles.css │ │ └── 3_css_in_js_snapshots/ │ │ ├── ActionLog.jsx │ │ ├── ActionLog.test.jsx │ │ ├── App.jsx │ │ ├── App.test.jsx │ │ ├── ItemForm.jsx │ │ ├── ItemForm.test.jsx │ │ ├── ItemList.jsx │ │ ├── ItemList.test.jsx │ │ ├── __mocks__/ │ │ │ └── react-spring/ │ │ │ └── renderprops.jsx │ │ ├── __snapshots__/ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ ├── App.test.jsx.snap │ │ │ └── ItemList.test.jsx.snap │ │ ├── babel.config.js │ │ ├── constants.js │ │ ├── index.html │ │ ├── index.jsx │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ ├── setupJestDom.js │ │ ├── setupJestEmotion.js │ │ └── styles.css │ ├── 4_component_stories/ │ │ ├── 1_stories/ │ │ │ ├── .storybook/ │ │ │ │ └── main.js │ │ │ ├── ActionLog.jsx │ │ │ ├── ActionLog.stories.jsx │ │ │ ├── ActionLog.test.jsx │ │ │ ├── App.jsx │ │ │ ├── App.test.jsx │ │ │ ├── ItemForm.jsx │ │ │ ├── ItemForm.stories.jsx │ │ │ ├── ItemForm.test.jsx │ │ │ ├── ItemList.jsx │ │ │ ├── ItemList.stories.jsx │ │ │ ├── ItemList.test.jsx │ │ │ ├── __mocks__/ │ │ │ │ └── react-spring/ │ │ │ │ └── renderprops.jsx │ │ │ ├── __snapshots__/ │ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ │ ├── App.test.jsx.snap │ │ │ │ └── ItemList.test.jsx.snap │ │ │ ├── babel.config.js │ │ │ ├── constants.js │ │ │ ├── index.html │ │ │ ├── index.jsx │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── setupGlobalFetch.js │ │ │ ├── setupJestDom.js │ │ │ ├── setupJestEmotion.js │ │ │ └── styles.css │ │ └── 2_documentation/ │ │ ├── .storybook/ │ │ │ └── main.js │ │ ├── ActionLog.jsx │ │ ├── ActionLog.stories.jsx │ │ ├── ActionLog.test.jsx │ │ ├── App.jsx │ │ ├── App.test.jsx │ │ ├── ItemForm.jsx │ │ ├── ItemForm.stories.jsx │ │ ├── ItemForm.test.jsx │ │ ├── ItemList.jsx │ │ ├── ItemList.stories.jsx │ │ ├── ItemList.stories.mdx │ │ ├── ItemList.test.jsx │ │ ├── __mocks__/ │ │ │ └── react-spring/ │ │ │ └── renderprops.jsx │ │ ├── __snapshots__/ │ │ │ ├── ActionLog.test.jsx.snap │ │ │ ├── App.test.jsx.snap │ │ │ └── ItemList.test.jsx.snap │ │ ├── babel.config.js │ │ ├── constants.js │ │ ├── index.html │ │ ├── index.jsx │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── setupGlobalFetch.js │ │ ├── setupJestDom.js │ │ ├── setupJestEmotion.js │ │ └── styles.css │ └── server/ │ ├── README.md │ ├── authenticationController.js │ ├── authenticationController.test.js │ ├── cartController.js │ ├── cartController.test.js │ ├── dbConnection.js │ ├── disconnectFromDb.js │ ├── inventoryController.js │ ├── jest.config.js │ ├── knexfile.js │ ├── logger.js │ ├── migrateDatabases.js │ ├── migrations/ │ │ ├── 20200325082401_initial_schema.js │ │ └── 20200331210311_updatedAt_field.js │ ├── package.json │ ├── seedUser.js │ ├── seeds/ │ │ └── initial_inventory.js │ ├── server.js │ ├── server.test.js │ ├── truncateTables.js │ └── userTestUtils.js ├── chapter9/ │ ├── 1_the_philosophy_behind_tdd/ │ │ ├── 1_what_tdd_is/ │ │ │ ├── 1_small_test/ │ │ │ │ ├── calculateCartPrice.js │ │ │ │ ├── calculateCartPrice.test.js │ │ │ │ └── package.json │ │ │ ├── 2_partial_test/ │ │ │ │ ├── calculateCartPrice.js │ │ │ │ ├── calculateCartPrice.test.js │ │ │ │ └── package.json │ │ │ ├── 3_extra_test/ │ │ │ │ ├── calculateCartPrice.js │ │ │ │ ├── calculateCartPrice.test.js │ │ │ │ └── package.json │ │ │ └── 4_handling_edge_cases/ │ │ │ ├── calculateCartPrice.js │ │ │ ├── calculateCartPrice.test.js │ │ │ └── package.json │ │ └── 2_adjusting_iteration_size/ │ │ └── 1_bigger_steps/ │ │ ├── calculateCartPrice.js │ │ ├── calculateCartPrice.test.js │ │ ├── package.json │ │ ├── pickMostExpensive.js │ │ └── pickMostExpensive.test.js │ └── 2_writing_a_js_module_using_tdd/ │ ├── 1_generating_item_rows/ │ │ ├── inventoryReport.js │ │ ├── inventoryReport.test.js │ │ └── package.json │ ├── 2_generating_total_row/ │ │ ├── inventoryReport.js │ │ ├── inventoryReport.test.js │ │ └── package.json │ └── 3_creating_report/ │ ├── inventoryReport.js │ ├── inventoryReport.test.js │ └── package.json └── package.json