{"_id":"@airtable/blocks-testing","_rev":"50-43d845ad162fd278b6f4bbd5e24ef281","name":"@airtable/blocks-testing","dist-tags":{"experimental":"0.0.4-experimental-68738f2-20220526","latest":"0.0.6"},"versions":{"0.0.1":{"name":"@airtable/blocks-testing","version":"0.0.1","author":{},"license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.1","maintainers":[{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"benrazon","email":"ben.razon@airtable.com"},{"name":"billy.airtable","email":"billy.littlefield@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jbbakst","email":"jbbakst@gmail.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"montrey","email":"montrey@airtable.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"somehats","email":"alex@dytry.ch"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"josemdv","email":"jose@martindv.es"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"k8r","email":"kate.rudolph@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","dist":{"shasum":"7270581eb23e09f48cfcebf8a39c8d640daef2b2","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.1.tgz","fileCount":41,"integrity":"sha512-cftvgH4KRhzbtUZs8ORWJOudqlxXsSgCcn6yh+BBFvhRaImAjCgZDjKpNYOu4iPTK3JA77dYhLmVJUb3kEZZ6A==","signatures":[{"sig":"MEUCIQDGBYCr5jBpwO8c/04kIkLuc7mjscsqq1FCioO1m9E9wAIgY3Ltwdgb5tWTWB+Sobzpc8F3Hf3X2CYG81nmBnaL1/I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108564,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPi5aCRA9TVsSAnZWagAAeiAQAJUu1diMvqWzOp4dqs3d\nkXbzUSmltD/JJUxDvWUF1NTLh6E72BCWALZGGdAB31h+0Wkm3MeVdHMkC2pa\nBdE+duCMwXHvs9LnUXeo6eY3dEN3c+TaUrtqAF+IE74BW7mNI240OMNCQcIq\nosOVlC9XHD4qz6iN4qPnLrV4ScZjviBrcqhvzve9LjbWi05SAPEUcmjpx4NZ\nhw0CTO228tP299bz+l1L19nCSXo6fgEKjBZkEpmoAzpiBWC0Yzlrocu0wVfq\nLx8TErgeGXNOEoU6sFM9rSx7QPhPf0mTg5tCHQmlzVDbKmhvupPnqh8HWrsN\nxMqKkt6wPNDxXfnez2xOc6T/cITE5ODjkcrPis+wNCrHF9ykVW2rAbAVm5Sf\ncz5pRFvPdNYrIHN7+DzxXSc1sEAarpUlXNtqnmtYqdZuq8op42ot4N76KcnQ\ngERmiMuxRCCyy+UL0PzUN2WmXs14EtDhtSV5MSKFlA9oD0rixJCPoktoCTtr\nkTBdot3Z4dBaK6IaAUCIpLqd+c5XjXmM/hTv363aBOoIxA2cjWl8ZOOxBvi2\nq9nzvBukwYMxqYCjA+aFEkXmGDzJifelhRAMzsaC/Y9Hcm7HOgpAZ9LDSl82\n5dmxsSKCvivx18EyWtNVj6E0v0NfVM/qftnNclaUn+r+MZBP/bxScJLiCrdf\n1549\r\n=ihCH\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"index.d.ts","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run docs && yarn run test:coverage","docs":"yarn build && yarn run docs:clean && yarn run docs:generator && yarn run docs:typedoc && yarn run docs:minify-docs-json","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && yarn run docs && git add CHANGELOG.md docs/docs-$npm_package_version.json","docs:clean":"rm -rf ./doc-generator/lib $(find . -regex '.*docs-[0-9]*\\.[0-9]*\\.[0-9]*\\.json')","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","docs:typedoc":"typedoc --plugin \"typedoc-plugin-no-inherit,$(pwd)/doc-generator/typedoc-plugin.js\" --json ./docs/docs-$npm_package_version.json .","test:coverage":"yarn run test --coverage","docs:generator":"tsc -b ./doc-generator/tsconfig.json","docs:minify-docs-json":"node ./doc-generator/minify-docs-json.js ./docs/docs-$npm_package_version.json"},"_npmUser":{"name":"somehats","email":"alex@dytry.ch"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"(cd ../../ && tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version})"}},"repository":{"url":"https://github.com/Airtable/blocks-testing.git","type":"git"},"description":"Airtable Blocks Testing Library","directories":{},"dependencies":{"core-js":"^3.4.8","@types/react":"^16.9.5","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.4.1","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.4.1"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.1_1614687833582_0.562188423878984","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@airtable/blocks-testing","version":"0.0.2","author":{},"license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.2","maintainers":[{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"benrazon","email":"ben.razon@airtable.com"},{"name":"billy.airtable","email":"billy.littlefield@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jbbakst","email":"jbbakst@gmail.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"montrey","email":"montrey@airtable.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"somehats","email":"alex@dytry.ch"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"josemdv","email":"jose@martindv.es"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"k8r","email":"kate.rudolph@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","dist":{"shasum":"7a6d0b277b95cfce9ed6a4f8fed2775b941f0495","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.2.tgz","fileCount":41,"integrity":"sha512-NrOovc/Un7Ojd5I7HrWCXra5OWI8SUpb2N4ivEmIIPnMoVWLjRX4XgOdQI2k/mqd3fTZ9ziJzRn0PxTYfoH7rg==","signatures":[{"sig":"MEUCIG6Ov6nzUqqWLF04szsmaxo3jvu6Tv+ZNssN5L6a8CLCAiEA40WaPG3l3qA1VEc4qGyjT+iBSc8I9U69pVWCPYHU8GU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108690,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgQTGRCRA9TVsSAnZWagAANSQP/0jjKvn/YKbQ5B+sCKQv\n7S/4dDOYwYyJfSEOcu17KjgFynA1IDMjmVwnBRQomNYubw2jQ87T+VLJA5XL\nwqdwsna4J6vC25kVg2Se6csDvzHX7ZBUNsd33MBtU1iBH03DzYo2vQ9gdgga\n/HFY0C++tMZbsbU/RpnKVtLQJAfh853YtrblHgyQ4PTgBc/SX+E5XiFKsXdV\ncveIoEVhFvxQoZUjWsTRVGWfMAT8VfWjATERg7ta/wMkxh1HmuUV9CXnMpw9\nzHXx6BgHhcwH10tKZz7W/sGBQm7NcTEt9PcS2g6O7IWl6+ChfliKnJglDMdB\nV90/OWHGa2J9eWH2CTGXlitDC8l5Znm8Kz6EM51f5QmpyBkyoO97ikMdPBJg\nFxzoXE9MsgyoApsHZ6cSVTYlnGd6c2psAZsgh+jUSjTtLxYLzIuZaBI1xgLO\nsMtuxerzaIhv2FQcH5hzfmdRvhlYAy1EDDxuqpSeACEx+euenqUmSXET/rgg\npXKG6nLXpkQXnO4A076UUsijhLqY3EYd+7pFgWUeZTkTIPALyaDEtWb07TCt\njVyIXq8iR+YSZ2NbGduK761OtBxDBJfN2hEe+VpmjIJuuocwaeT4/84iRV7b\nVF6MZEQrxKJf/A50w06lhNAGoSttFEL9ZkQzEe3m45JDUTcQsq6zSPYr+0GS\nVe04\r\n=m/JC\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"index.d.ts","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run docs && yarn run test:coverage","docs":"yarn build && yarn run docs:clean && yarn run docs:generator && yarn run docs:typedoc && yarn run docs:minify-docs-json","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && yarn run docs && git add CHANGELOG.md docs/docs-$npm_package_version.json","docs:clean":"rm -rf ./doc-generator/lib $(find . -regex '.*docs-[0-9]*\\.[0-9]*\\.[0-9]*\\.json')","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","docs:typedoc":"typedoc --plugin \"typedoc-plugin-no-inherit,$(pwd)/doc-generator/typedoc-plugin.js\" --json ./docs/docs-$npm_package_version.json .","test:coverage":"yarn run test --coverage","docs:generator":"tsc -b ./doc-generator/tsconfig.json","docs:minify-docs-json":"node ./doc-generator/minify-docs-json.js ./docs/docs-$npm_package_version.json"},"_npmUser":{"name":"benrazon","email":"ben.razon@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"(cd ../../ && tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version})"}},"repository":{"url":"https://github.com/Airtable/blocks-testing.git","type":"git"},"description":"Airtable Blocks Testing Library","directories":{},"dependencies":{"core-js":"^3.4.8","@types/react":"^16.9.5","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.5.0","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.5.0"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.2_1614885265033_0.7236770231968557","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"@airtable/blocks-testing","version":"0.0.3","author":{},"license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.3","maintainers":[{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"benrazon","email":"ben.razon@airtable.com"},{"name":"billy.airtable","email":"billy.littlefield@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jbbakst","email":"jbbakst@gmail.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"montrey","email":"montrey@airtable.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"somehats","email":"alex@dytry.ch"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"josemdv","email":"jose@martindv.es"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"k8r","email":"kate.rudolph@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","dist":{"shasum":"62216067ec60499c6378126a2b0a772f22d1f444","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.3.tgz","fileCount":41,"integrity":"sha512-Hrn2v//JKeQDgHCvnEqPPgCTcMi/5mMoo4+wKICT+GmG0dkKqn5JnrEjhYZz69K2AkJXt33hPciq1Oz9iKGVkQ==","signatures":[{"sig":"MEQCIGLm4ODoTI5D7r/CUjQKJhm/KG6TXsreGAspM/YOrrxTAiAucTKmgHt2VAAfEJ0RnPgXSAEF7xLz8QehTscHHeRtfQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108570,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgQnjNCRA9TVsSAnZWagAAspoP/iMIPbQRdscS+AmCb+V3\ng6gDEap2qX6IjsSngkPHfNltMdgTAejv1IZ9mKvfFIWSakWy9I8cb94EsaiM\nmNx3T09B3QF0pBvC92jLrIMayxJpaCirUjrQBS+tBt9R7h0Bf8OnQgC4HuFy\nkbJmPmnAQfQ+o93ixlzBio7YPFerW8RvXrOASmJ16Tv5QDHL7S5ryS9YIttY\n9SeZv0+2nhRfsDJIZE05SHeY3L4rmd9Z18F89DQxI1t+F1G5yiFXWRkRXfK0\n1VF8Vb8WUcCWfqJAMuPhDCokEATXz73+2PaX28xwE7lP6ZfmELHB0KJ/6TQ5\n3ROrIXUXh6y0NjgLziQEJ378UgcQMimI18XgrFTT3M7ZQ04BHB1K/an8Y9Bt\nML+g32unO/e9z+uN6FfL56hy8xEfDftOtOOROztFrX4T4WP41J4bSifFluSb\nTDqIZOZj8Kj0dqD9tjnwSam4T1BQYAE68gP75QHqm9oO5pQtAG2jYil5QjaG\nJdgxFASfNEm6bKSe21eOOdeS1qVx3S+PYxua8M/iBPO5F8Ahbrhx2CA6Q4cI\nuu8NJ2JAkbvLnQ61my0eypfgnAYoSRHtWCH+CRoGKQWa4oFXZp+HVPnpnJwy\naRuYDO13VByRrwNGUMK+Hza9aFSVs376nNPHq2yn8EtBWRIRuwAWkcQsGFSi\nm8rD\r\n=9rZ2\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"index.d.ts","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run docs && yarn run test:coverage","docs":"yarn build && yarn run docs:clean && yarn run docs:generator && yarn run docs:typedoc && yarn run docs:minify-docs-json","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && yarn run docs && git add CHANGELOG.md docs/docs-$npm_package_version.json","docs:clean":"rm -rf ./doc-generator/lib $(find . -regex '.*docs-[0-9]*\\.[0-9]*\\.[0-9]*\\.json')","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","docs:typedoc":"typedoc --plugin \"typedoc-plugin-no-inherit,$(pwd)/doc-generator/typedoc-plugin.js\" --json ./docs/docs-$npm_package_version.json .","test:coverage":"yarn run test --coverage","docs:generator":"tsc -b ./doc-generator/tsconfig.json","docs:minify-docs-json":"node ./doc-generator/minify-docs-json.js ./docs/docs-$npm_package_version.json"},"_npmUser":{"name":"benrazon","email":"ben.razon@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test"}},"repository":{"url":"https://github.com/Airtable/blocks-testing.git","type":"git"},"description":"Airtable Blocks Testing Library","directories":{},"dependencies":{"core-js":"^3.4.8","@types/react":"^16.9.5","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.5.1","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.5.1"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.3_1614969037146_0.5536461681908711","host":"s3://npm-registry-packages"}},"0.0.4":{"name":"@airtable/blocks-testing","version":"0.0.4","author":"","license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.4","maintainers":[{"name":"jamesmoody-at","email":"james.moody@airtable.com"},{"name":"adarlieberdembo","email":"adar@airtable.com"},{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"benrazon","email":"ben.razon@airtable.com"},{"name":"billy.airtable","email":"billy.littlefield@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jbbakst","email":"jbbakst@gmail.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"montrey","email":"montrey@airtable.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"somehats","email":"alex@dytry.ch"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"josemdv","email":"jose@martindv.es"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"k8r","email":"kate.rudolph@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","bugs":{"url":"https://github.com/Airtable/blocks-testing/issues"},"dist":{"shasum":"0fcbac7e97e5cb5e1d1053a787f994762d08b48b","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.4.tgz","fileCount":42,"integrity":"sha512-1jl3x5ZG0AB8dnB9d1oJm5hswGKcz+vd4XDA1Zi25RjPDray5YXMI0kEwEhTvxxUWTRGWaYiBOQ1x7ab634XbA==","signatures":[{"sig":"MEUCIEq7fTYLs855HcUNEt/8Gj1htxAfOpQuSEfymNwsUPtBAiEAv13xuvtfbpMumDtu8OqT6vog7UfwJGFShv2IdfCeD/s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":137299,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJggvzaCRA9TVsSAnZWagAAf+cP/3BL/qZdGJtYBt7kmf4D\ncz/MZZ/phtzSRcnRHvWehL6NMC4+V6X6hYPSR3oEjHgnd/Ms5StDdEi6sF5I\nPMbT8bFfMJh+vWtCnfJneFQ2aUsiEi0m3jFwJN6z+cAkBjqth3rrdp4FIv0o\nJHDcy5OxfNH3MLPiWG+Hzix9zVj/cCZbVuBNWgScDaG0/vNvniLfNGf9r+uJ\nhFjgLr+Q8XbpmbyVRrhUjoWiUsGSM0qqpG0fQDQVwHplmrzw3OQDPhsfj8hm\nHrc2jXEuxNtkyg6JfxjUfH/yUoI0B1w/Z43Bp9uVMdjVRgsoJ5ltO6xbstgY\n2iGUls6bqPnso/VoTxiK/+KRuTPokFddwbZTls/uzwY0fV+iNZgh40XHdhND\nkGIfrz9gxqEkaTvXiajwXUqb+8CRkg34VFHHBVyXKW+jEsKQcGbd6uu6C1CK\nM9aG/DU6y+XMGl9X0Gq5Le8xlMh7gLFzJ4m6LXXLgE3TPXN4OnP6fzwQwtWj\ne0b6dqF5CTRXbNFO/HVsFF2pl2fnE9kS6yaXw6x+UFHR0nc7gm64OVnbx/Nn\n8g9h1aWvHK3as+4nAs46jt60mIYQhUQ9oiQxPZDBtvxXyCj97nJB9/xzb2Fl\nCBxc+zcdPnZ+gljDLjMd2GhQMZKU5xiYh0sKtpO9Lf1V6Q7VVKJQBFM7xxmZ\nFNNe\r\n=WQKK\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"dist/types/src/index.d.ts","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run test:coverage && ./scripts/check_integration_with_sdk.sh","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && git add CHANGELOG.md","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","test:coverage":"yarn run test --coverage"},"_npmUser":{"name":"benrazon","email":"ben.razon@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"(cd ../../ && tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version})"}},"repository":{"url":"git+https://github.com/Airtable/blocks-testing.git","type":"git"},"_npmVersion":"6.14.10","description":"Airtable Blocks Testing Library","directories":{},"_nodeVersion":"12.20.1","dependencies":{"semver":"^7.3.4","core-js":"^3.4.8","@types/react":"^16.9.5","@types/semver":"^7.3.4","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.5.1","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","babel-plugin-transform-define":"^2.0.0","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.5.1"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.4_1619197145807_0.5499267044873355","host":"s3://npm-registry-packages"}},"0.0.4-experimental-68738f2-20220526":{"name":"@airtable/blocks-testing","version":"0.0.4-experimental-68738f2-20220526","author":"","license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.4-experimental-68738f2-20220526","maintainers":[{"name":"hongda.jiang","email":"hongda.jiang@airtable.com"},{"name":"willpowelsonat","email":"will.powelson@airtable.com"},{"name":"naitiy","email":"yitian.zhang@airtable.com"},{"name":"emilia.gabryszewska","email":"emilia@airtable.com"},{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"billy.airtable","email":"billy.littlefield@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"somehats","email":"alex@dytry.ch"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"josemdv","email":"jose@martindv.es"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"},{"name":"adarlieberdembo","email":"adar@airtable.com"},{"name":"jamesmoody-at","email":"james.moody@airtable.com"},{"name":"pete.viri","email":"pete.viri@airtable.com"},{"name":"kevinwilde-at","email":"kevin.wilde@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","bugs":{"url":"https://github.com/Airtable/blocks/issues"},"dist":{"shasum":"34d606051c3f22df895e5769cf8390c6859515c2","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.4-experimental-68738f2-20220526.tgz","fileCount":41,"integrity":"sha512-4xzxvnG4KwT3R5HeYivn8nRd2vjmHbSidwDgNOqV8HOqKD/TPeeChoniz5pCZr+Mwb6P/vpxreBYKIYvgKn20A==","signatures":[{"sig":"MEQCICn/vMpJJyXR1SdZPFkW+OGzaM1lL7LiO1igVwc7CtggAiBilv3GB6JOWScjXOr5dXewYwlSbj2fOP4nY+nAZ2HiHA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJij8smACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRLg/9Ft//7KNP7pS7DGxHmmHcBS6xU9Kcbjfqq89ipnxWQB+8vgw0\r\njJqk/FmMFLDQ0aKRDXL7/OYsOdwVLyWVHtxjYxLEgZi2NhguptxfJBxZEjbX\r\nDjWXS98UwokWGP+i30ca1AoquC+x4ObgbuYKDnk9FrbgCidmuCJTY3DLwo1w\r\nlrwrqzZuUF6T2PE52qPM8vABqIpK3S7bKHWbyoA8V0g2FpLL7tjgZgyjKE33\r\n2kEUC1OWSBlH4kqLzrAzv//u8+kxMwU78W/gJmA65gYdI6/W4zh8/g7OTdJd\r\nS8cXsvsbLSKdNX6eJfDxzKV3h3o4as35tclbgg/8rxoJi9UwEhtI0R4V5ozK\r\nBGY8+a9MS8e8uQFi1C2XDGAZx0F4NkOh7S9kmAQGPwsIWjpfUKufF8ATrg+L\r\n+QfiK/6NNza4USBou8oH9empKI0QcAjRVn9VPC9fuvMMIyEiRF7NG/MNK1D7\r\nWG9fEfnZBGx96l0jnQBJQS7dY4iDlrIjk21ErHA6AFvuJo3mz9/gIzDOAR/L\r\nygL5m1LFt/G4B1i01G8Ottlew6q8dQZTINhWvRY64U+p5XProh+9X3Vi4Lhy\r\nSZVvmBFV96Jh3Ui8mke9qqNpiR7NXM2drG3wJo93RY8eNbP6IQm0I/y8S6BD\r\ndT12zMNS/ldTnml/R/W3q16kBAbuI5o++NA=\r\n=bVrJ\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"dist/types/src/index.d.ts","readme":"# Introduction to writing automated tests for Airtable Apps\n\nSupport for automated testing is currently in open beta.\n\n## Implementation status\n\nNot all operations are currently supported. In the course of writing tests, authors may find that\nthe App under test does not function as intended when induced to perform these operations. Authors\nmay request support from the SDK maintainers or implement the functionality they need as part of\ntheir work (this document includes guidance on extending the testing API in a subsequent section).\n\nThe following table describes the implementation status of each operation.\n\n| operation                 | internal support   | testing API        |\n| ------------------------- | ------------------ | ------------------ |\n| Table - create            | partial [1]        |\n| Table - update            | partial [1]        |\n| Table - destroy           |                    | :heavy_check_mark: |\n| Field - create            | partial [1]        |\n| Field - update            | partial [1]        |\n| Field - destroy           |                    | :heavy_check_mark: |\n| View - create             |                    |\n| View - update             |                    |\n| View - destroy            |                    | :heavy_check_mark: |\n| Global Config - update    | :heavy_check_mark: | n/a [2]            |\n| Cursor Data - update      |                    | :heavy_check_mark: |\n| Session Data - update     |                    |\n| User permissions - update | :heavy_check_mark: | :heavy_check_mark: |\n| click settings button     |                    |\n| toggle full screen        |                    |\n| expand record             |                    | :heavy_check_mark: |  |\n| Record - create           | partial [3]        | n/a [2]            |\n| Record - update           | :heavy_check_mark: | n/a [2]            |\n| Record - destroy          | :heavy_check_mark: | n/a [2]            |\n\n-   [1] While the SDK's public API supports these operations, its capabilities are restricted.\n    Ideally they would be complemented by a more powerful testing API.\n-   [2] These operations can be initiated using the SDK's public API.\n-   [3] Unsupported operations: creating records for tables which have not yet been loaded,\n    [creating records with data for fields which have not yet beean loaded](https://github.com/Hyperbase/blocks-sdk/blob/a77fa4b959f512a041e987ee0bfe3fafb7db8b59/packages/sdk/src/models/mutations.ts#L583),\n    and creating records in specific views\n\n## Key concepts\n\n**Test fixture data** is a representation of the state of an Airtable Base, including descriptions\nof Tables, Views, Fields, and Records. It is written by test authors and in terms of\nJSON-serializable values.\n[The App Test Fixtures Airtable App](https://airtable.com/marketplace/blk5qI32GYyYb1Rbm/test-fixture-generator)\nallows developers to generate this data from the state of an authentic Base. This App is not ready\nfor beta yet.\n\n**`TestDriver`** is the JavaScript interface for creating and manipulating a simulated Airtable Apps\nenvironment. It implements methods for performing operations which are not available in the SDK.\n\n**`AirtableInterface`** is the layer of the SDK which mediates between the models and the backend.\nIn production environments, it operates via asynchronous message passing with the App's parent web\nbrowser frame. In testing environments, no transmission occurs, but the `AirtableInterface` behaves\nas though it is receiving relevant messages in order to simulate production behavior.\n\n**Mutations** are instructions which describe changes to the Base. Mutations travel through the\n`AirtableInterface`, which sends them to the backend in production environments only.\n\n## Writing tests\n\nAs of January 2021, Airtable Apps must be written using the React framework. These instructions take\nthe presence of React for granted.\n\nEvery test file must import TestDriver through the `@airtable/blocks-testing` module to ensure that\nthe environment is correctly instrumented for automation.\n\nEach test will typically perform the following steps:\n\n1.  Create a TestDriver instance, providing valid fixture data:\n\n    ```js\n    const testDriver = new TestDriver({\n        /* fixture data here */\n    });\n    ```\n\n2.  Create an instance of the App under test by rendering the App's Component as a child of the\n    `TestDriver#Container` Component.\n\n    ```js\n    render(\n        <testDriver.Container>\n            <MyApp />\n        </testDriver.Container>,\n    );\n    ```\n\n3.  Provide some input to the App. This may be in the form of a simulated user interaction (e.g. via\n    [the `@testing-library/user-event` library](https://www.npmjs.com/package/@testing-library/user-event))\n\n    ```js\n    // Simulate a user choosing the \"Gruyere\" option from the table labed\n    // \"Cheeses\".\n    const input = screen.getByLabelText('Cheeses');\n    const option = screen.getByText('Gruyere');\n    userEvent.selectOptions(input, [option]);\n    ```\n\n    ...or a simulated backend behavior (e.g. via\n    [the Blocks SDK](https://airtable.com/developers/apps) or the `TestDriver` API).\n\n    ```js\n    // Invoking `createTableAsync` in a test script simulates the condition\n    // where the Airtable backend reports that a table has been created by\n    // another viewer of the Base.\n    await testDriver.base.createTableAsync('a new table', [\n        {name: 'address', type: FieldType.EMAIL},\n    ]);\n    ```\n\n4.  Verify that the App responded to the input as expected. For many kinds of interactions, the\n    App's response will be discernible by some change in the UI.\n    [The `@testing-library/react` library](https://www.npmjs.com/package/@testing-library/react) is\n    a good choice for inspecting the state of the user interface.\n\n    ```js\n    // Ensure that the UI updated to display the checkbox as \"checked\"\n    const checkbox = screen.getByRole('checkbox');\n    expect(checkbox.checked).toBe(true);\n    ```\n\n    ...while the `TestDriver` API can be used to verify App behaviors which do not influence the UI:\n\n    ```js\n    // Track every time the App attempts to expand a record.\n    const recordIds = [];\n    testDriver.watch('expandRecord', ({recordId}) => recordIds.push(recordId));\n\n    // (The code necessary to simulate user inteaction elided from this example.)\n\n    // Ensure that the App attempted to expand the Record with ID `reca`\n    expect(recordIds).toEqual(['reca']);\n    ```\n\n[The automated test suite for the To-do List example App](https://github.com/Airtable/apps-todo-list/tree/master/test)\ndemonstrates this pattern.\n\n## Extending the Testing API\n\nIn order to provide predictable behavior, the Airtable testing platform relies on simulations of\nBase operations. Every simulation requires some amount of support in the testing platform. Some\nsimulations also require a dedicated testing API.\n\n**Implementing internal support** Every Base operation requires some amount of simulation code in\norder to support scripting in test environments.\n\nFor some operations, this simulation may be as limited as a \"no-op\" implementation of an internal\nmethod. These operations include mutations which the SDK applies optimistically and messages with no\ndirect effect on the App.\n\nOther operations will require more advanced simulation logic. Operations of this type generally rely\non the backend's response to determine their effect on the Base. The simulated behavior should be\npredictable, mimicking the expected response in production.\n\n**Implementing a dedicated API** A dedicated testing API is not necessary for any operation which\ncan be expressed through the public API of the SDK (e.g. \"create many records\" or \"delete a table\").\nWhen a test author wishes to script such an operation, they should use the SDK directly. This is\nvalid because an App cannot distinguish between operations initiated by the backend and operations\ninitiated by a test script using the SDK.\n\nMany other operations cannot be expressed via the public API of the SDK. The `TestDriver` API must\nbe extended to allow test authors to simulate these operations.\n\nSome of these restrictions are circumstantial, owing to the fact that as of January 2021, the SDK is\nincomplete and under active development. This includes an API to delete a Field. Other restrictions\nare fundamental to the design of the Apps platform. For instance, the SDK intentionally omits a\nmethod for an App to change the permissions of the current user. This distinction may inform the\ndecision to introduce a testing API, since doing so will increase maintenance responsibilities in a\nway that may be obviated by future extensions to the SDK's public API.\n","gitHead":"68738f2c47ea1d917b245ddf45203b0f8e5733f3","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run test:coverage && ./scripts/check_integration_with_sdk.sh","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && git add CHANGELOG.md","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","test:coverage":"yarn run test --coverage"},"_npmUser":{"name":"seankeenan-at","email":"sean.keenan@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"../../tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version}"}},"repository":{"url":"git+https://github.com/Airtable/blocks.git","type":"git"},"_npmVersion":"8.1.2","description":"Airtable Blocks Testing Library","directories":{},"_nodeVersion":"16.13.1","dependencies":{"semver":"^7.3.4","core-js":"^3.4.8","@types/react":"^16.9.5","@types/semver":"^7.3.4","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.11.1-experimental","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","babel-plugin-transform-define":"^2.0.0","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.11.1-experimental"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.4-experimental-68738f2-20220526_1653590822073_0.41234286159735745","host":"s3://npm-registry-packages"}},"0.0.5":{"name":"@airtable/blocks-testing","version":"0.0.5","author":"","license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.5","maintainers":[{"name":"blakethomson-at","email":"blake.thomson@airtable.com"},{"name":"hongda.jiang","email":"hongda.jiang@airtable.com"},{"name":"willpowelsonat","email":"will.powelson@airtable.com"},{"name":"naitiy","email":"yitian.zhang@airtable.com"},{"name":"emilia.gabryszewska","email":"emilia@airtable.com"},{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jeroenransijn","email":"jssrdesign@gmail.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"kahseng_at","email":"kahseng.tay@airtable.com"},{"name":"maryrosecook","email":"mary@maryrosecook.com"},{"name":"philipl-airtable","email":"philip.langdale@airtable.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"seandonoghue","email":"sean.donoghue@airtable.com"},{"name":"shrey-at","email":"shrey.banga@airtable.com"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"timdeng-at","email":"tim.deng@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"},{"name":"adarlieberdembo","email":"adar@airtable.com"},{"name":"jamesmoody-at","email":"james.moody@airtable.com"},{"name":"kevinwilde-at","email":"kevin.wilde@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","bugs":{"url":"https://github.com/Airtable/blocks/issues"},"dist":{"shasum":"c11083bfc5247870d1f9ff5cc56a68f16ae40979","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.5.tgz","fileCount":41,"integrity":"sha512-ZZOp/iD7vyGW7aZ9X4gaFF29ODDqOWsKqd2HTfLUNA7dRYG5R900fdn9+cmqUZqlDEkve7j+ADzcIhZMu/YAqQ==","signatures":[{"sig":"MEQCIEeYxvsw5WD//jh3SuiFNb+5J2gZsQ8fAuoI0apVON5AAiB1T1wv52es5/g/4mh+ItdtorcKmp+gUoSy00xy1WmnWg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":139336,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjLkZCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHzQ//eWzDlK9AGoCMJWFXOzN/vU5NBHlaR7OtajiIlXuAH4zPWolP\r\nGfJ82qJrVLiBs9YgUsoXAsZhyyGpansSSzztKMQ1M3GtWMPwB7/lW4Ufui37\r\nnt0XAqy8F5d7sOb+LU97gFp1BxvdeU/FNW8+v97fFUkliymFiAr2Q694UaMW\r\nkKxYgHFv4ENctJmttpmGeg7iUhewHq8Q1GJCcWTZtoM341AFRrsMaw+oMXVl\r\najRf0BE2ti1SegerSRORJIBPEXrhuz8hHYFJj8SK2oOtOpK9lesYGKmzSD56\r\nBqZyj2hYZyk2GnZ+D36GbSuGN+/Tn638Azfod7x9EIhgeNx9N5dDE1ox9KIW\r\nlEP3P8nbnVcxl49/jNXKmPPAiJ50Mt+z+AfFzRLjmVJIj42nk6w2XGlDmqny\r\nT3LjnP12k622jVZoVkNLvuyZhEby6U+dcpPfyIH8LVKgw7vpFGC+1rwWKTrC\r\no3JZnSQ5SNZe/+SqLUYw/nvUDAzbCg2DmxXdVfgEVjDwkIYQrgrUk4oe4j9u\r\nPRwhQo35a53BFl2bZQCJ/VjMSwm9JpaAA76t73I5R086n2Q2hn+k7/lNBKFc\r\nk+J2/qtwhCW1EITe7PDyfvGt88+ilvcjbPkFwuvb32rPwVsP9PQA5UZmnE0O\r\nDQ9Ufam5Huxzfxv6guAwXtjUTjRw1IstiZw=\r\n=U2oR\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"dist/types/src/index.d.ts","gitHead":"3a5cf4b8cad1d2b2a2a944e56a140f0df59c5139","scripts":{"ci":"(cd ../sdk && yarn build) && yarn run build && yarn run test:coverage && ./scripts/check_integration_with_sdk.sh","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && git add CHANGELOG.md","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","test:coverage":"yarn run test --coverage"},"_npmUser":{"name":"emma_airtable","email":"emma@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"../../tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version}"}},"repository":{"url":"git+https://github.com/Airtable/blocks.git","type":"git"},"_npmVersion":"8.4.1","description":"Airtable Blocks Testing Library","directories":{},"_nodeVersion":"16.17.0","dependencies":{"semver":"^7.3.4","core-js":"^3.4.8","@types/react":"^16.9.5","@types/semver":"^7.3.4","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.5.1","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","babel-plugin-transform-define":"^2.0.0","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0","react-dom":"^16.8.0","@airtable/blocks":"^1.5.1"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.5_1663977026077_0.7474524973180259","host":"s3://npm-registry-packages"}},"0.0.6":{"name":"@airtable/blocks-testing","version":"0.0.6","author":"","license":"UNLICENSED","_id":"@airtable/blocks-testing@0.0.6","maintainers":[{"name":"nabeelairtable","email":"nabeel.f@airtable.com"},{"name":"clementhoang-at","email":"clement.hoang@airtable.com"},{"name":"it.ops","email":"it.ops@airtable.com"},{"name":"blakethomson-at","email":"blake.thomson@airtable.com"},{"name":"hongda.jiang","email":"hongda.jiang@airtable.com"},{"name":"willpowelsonat","email":"will.powelson@airtable.com"},{"name":"emilia.gabryszewska","email":"emilia@airtable.com"},{"name":"airtabledoug","email":"doug@airtable.com"},{"name":"airtable_ops_team_production","email":"opsteam+npmjsproduction@airtable.com"},{"name":"djmally-airtable","email":"david.mally@airtable.com"},{"name":"emma_airtable","email":"emma@airtable.com"},{"name":"jichu4n","email":"jichu4n@gmail.com"},{"name":"richsinn","email":"richard.sinn@airtable.com"},{"name":"s2tephen","email":"s2tephen@gmail.com"},{"name":"syrnick","email":"alex@airtable.com"},{"name":"manan_at","email":"manan.nayak@airtable.com"},{"name":"fredz-at","email":"fred.zhao@airtable.com"},{"name":"seankeenan-at","email":"sean.keenan@airtable.com"},{"name":"adarlieberdembo","email":"adar@airtable.com"},{"name":"kevinwilde-at","email":"kevin.wilde@airtable.com"}],"homepage":"https://airtable.com/developers/blocks","bugs":{"url":"https://github.com/Airtable/blocks/issues"},"dist":{"shasum":"ee14d2416332a010027ad40df31c03d9e038eab7","tarball":"https://registry.npmjs.org/@airtable/blocks-testing/-/blocks-testing-0.0.6.tgz","fileCount":42,"integrity":"sha512-GqpHQ60RFOaiiJT1OM4EDk9z0lTzlFPRxe6qgtjoHEWv8iwkVdY+PNhHgKusCXJwCvGy0AAzdQJEx7dixtTWmA==","signatures":[{"sig":"MEYCIQDDJ5yqedve4WQUoEnmqJVcSI1THAsoY231N5cw+kI8zgIhAKDiISDRzN8iTi1lEXfeZ2zWBDljWFpgUxuyu5wms/vT","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":141164},"jest":{"setupFiles":[],"coverageThreshold":{"global":{"lines":100,"branches":100,"functions":100,"statements":100}},"collectCoverageFrom":["src/**/*"]},"main":"dist/cjs/index.js","types":"dist/types/src/index.d.ts","scripts":{"ci":"echo '--- blocks-testing' && (cd ../sdk && yarn build) && yarn run build && yarn run test:coverage && ./scripts/check_integration_with_sdk.sh","jest":"node --unhandled-rejections=strict ./node_modules/.bin/jest","lint":"eslint --report-unused-disable-directives --ext .js,.ts,.tsx src test","test":"yarn run jest","build":"yarn run build:clean && concurrently yarn:build:babel yarn:build:types","types":"tsc","watch":"yarn run build:clean && concurrently yarn:watch:babel yarn:watch:types","pretest":"yarn run lint && yarn run types","release":"npm_config_registry=https://registry.npmjs.org/ release-it","version":"changelog-publish --github-repo-url='https://github.com/airtable/blocks-testing' --git-tag-prefix='@airtable/blocks-testing@' && git add CHANGELOG.md","jest:watch":"jest --watch","build:babel":"babel src --out-dir dist/cjs --extensions=.js,.ts,.tsx --ignore='**/*.d.ts'","build:clean":"rm -rf dist","build:types":"tsc --outDir dist/types --declaration --declarationMap --noEmit false --allowJs false --checkJs false --emitDeclarationOnly --stripInternal","watch:babel":"yarn run build:babel --watch --source-maps inline","watch:types":"yarn run build:types --watch","test:coverage":"yarn run test --coverage"},"_npmUser":{"name":"nabeelairtable","email":"nabeel.f@airtable.com"},"release-it":{"git":{"tagName":"@airtable/blocks-testing@${version}","commitMessage":"Release @airtable/blocks-testing@${version}"},"npm":{"access":"public"},"hooks":{"after:bump":"yarn build","before:init":"../../bin/check-repo-for-release && yarn build && yarn test","after:release":"../../tools/git-mirror/bin/git-mirror sync @airtable/blocks-testing@${version}"}},"repository":{"url":"git+https://github.com/Airtable/blocks.git","type":"git"},"_npmVersion":"6.14.10","description":"Airtable Blocks Testing Library","directories":{},"_nodeVersion":"16.16.0","dependencies":{"semver":"^7.3.4","core-js":"^3.4.8","@types/react":"^16.9.5","@types/semver":"^7.3.4","@babel/runtime":"^7.7.6","@types/prettier":"^1.19.0","@types/prop-types":"^15.7.3","@types/lodash.omit":"^4.5.6","@types/styled-system":"^5.1.4","@airtable/eslint-plugin-blocks":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^24.9.0","eslint":"6.7.2","typedoc":"^0.15.4","prettier":"^1.19.1","@babel/cli":"^7.7.5","typescript":"^3.7.3","@babel/core":"^7.7.5","@types/jest":"^24.0.23","@types/node":"^14.14.23","babel-eslint":"^11.0.0-beta.0","babel-loader":"^8.0.6","concurrently":"^5.0.0","@airtable/blocks":"^1.5.1","@types/react-dom":"^16.9.1","@babel/preset-env":"^7.7.6","@babel/preset-react":"^7.7.4","eslint-plugin-jsdoc":"^15.12.0","eslint-plugin-react":"^7.17.0","eslint-plugin-import":"^2.19.1","eslint-plugin-airtable":"github:hyperbase/eslint-plugin-airtable#01fef1f","@babel/preset-typescript":"^7.7.4","@typescript-eslint/parser":"^2.10.0","eslint-plugin-react-hooks":"^2.3.0","typedoc-plugin-no-inherit":"^1.1.10","babel-plugin-transform-define":"^2.0.0","@babel/plugin-transform-runtime":"^7.7.6","@typescript-eslint/eslint-plugin":"^2.10.0","@babel/plugin-proposal-class-properties":"^7.7.4","@babel/plugin-proposal-optional-chaining":"^7.7.5","@airtable-blocks-internal/changelog-publish":"^1.0.2","@babel/plugin-proposal-nullish-coalescing-operator":"^7.7.4"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0","react-dom":"^16.8.0 || ^17.0.0","@airtable/blocks":"^1.5.1"},"airtable_comments":{"@airtabel/blocks":["This version specifier should be as permissive as possible. It","should match the oldest version of the Blocks SDK with which the","testing library is known to function. It should also match the","specifier listed in this file's 'devDependencies'."]},"_npmOperationalInternal":{"tmp":"tmp/blocks-testing_0.0.6_1701357084373_0.163547905348292","host":"s3://npm-registry-packages"}}},"time":{"created":"2021-03-02T12:23:53.581Z","modified":"2026-04-30T20:58:59.537Z","0.0.1":"2021-03-02T12:23:53.808Z","0.0.2":"2021-03-04T19:14:25.152Z","0.0.3":"2021-03-05T18:30:37.306Z","0.0.4":"2021-04-23T16:59:06.133Z","0.0.4-experimental-68738f2-20220526":"2022-05-26T18:47:02.184Z","0.0.5":"2022-09-23T23:50:26.238Z","0.0.6":"2023-11-30T15:11:24.522Z"},"bugs":{"url":"https://github.com/Airtable/blocks/issues"},"license":"UNLICENSED","homepage":"https://airtable.com/developers/blocks","repository":{"url":"git+https://github.com/Airtable/blocks.git","type":"git"},"description":"Airtable Blocks Testing Library","maintainers":[{"email":"doug@airtable.com","name":"airtabledoug"},{"email":"opsteam+npmjsproduction@airtable.com","name":"airtable_ops_team_production"},{"email":"david.mally@airtable.com","name":"djmally-airtable"},{"email":"richard.sinn@airtable.com","name":"richsinn"},{"email":"s2tephen@gmail.com","name":"s2tephen"},{"email":"alex@airtable.com","name":"syrnick"},{"email":"adar@airtable.com","name":"adarlieberdembo"},{"email":"kevin.wilde@airtable.com","name":"kevinwilde-at"},{"email":"clement.hoang@airtable.com","name":"clementhoang-at"},{"email":"will.powelson@airtable.com","name":"willpowelsonat"},{"email":"blake.thomson@airtable.com","name":"blakethomson-at"},{"email":"nabeel.f@airtable.com","name":"nabeelairtable"},{"email":"lars.johnson@airtable.com","name":"larsj-at"},{"email":"caroline.kim@airtable.com","name":"carolinekimat"},{"email":"it.ops@airtable.com","name":"it.ops"},{"email":"anshul.tibrewal@airtable.com","name":"anshul2203"},{"email":"james.buzaid@airtable.com","name":"jbuzaid-airtable"},{"email":"boyang.sun@airtable.com","name":"boyang.sun"},{"email":"duretti.hirpa@airtable.com","name":"duretti-at"},{"email":"jonathan.xie@airtable.com","name":"jonathan.xie"},{"email":"patrick.liu@airtable.com","name":"patrickliu-at"},{"email":"derek.wu@airtable.com","name":"derekwu-at"}],"readme":"# Introduction to writing automated tests for Airtable Extensions\n\nSupport for automated testing is currently in open beta.\n\n## Implementation status\n\nNot all operations are currently supported. In the course of writing tests, authors may find that\nthe Extension under test does not function as intended when induced to perform these operations.\nAuthors may request support from the SDK maintainers or implement the functionality they need as\npart of their work (this document includes guidance on extending the testing API in a subsequent\nsection).\n\nThe following table describes the implementation status of each operation.\n\n| operation                 | internal support   | testing API        |\n| ------------------------- | ------------------ | ------------------ |\n| Table - create            | partial [1]        |\n| Table - update            | partial [1]        |\n| Table - destroy           |                    | :heavy_check_mark: |\n| Field - create            | partial [1]        |\n| Field - update            | partial [1]        |\n| Field - destroy           |                    | :heavy_check_mark: |\n| View - create             |                    |\n| View - update             |                    |\n| View - destroy            |                    | :heavy_check_mark: |\n| Global Config - update    | :heavy_check_mark: | n/a [2]            |\n| Cursor Data - update      |                    | :heavy_check_mark: |\n| Session Data - update     |                    |\n| User permissions - update | :heavy_check_mark: | :heavy_check_mark: |\n| click settings button     |                    |\n| toggle full screen        |                    |\n| expand record             |                    | :heavy_check_mark: |  |\n| Record - create           | partial [3]        | n/a [2]            |\n| Record - update           | :heavy_check_mark: | n/a [2]            |\n| Record - destroy          | :heavy_check_mark: | n/a [2]            |\n\n-   [1] While the SDK's public API supports these operations, its capabilities are restricted.\n    Ideally they would be complemented by a more powerful testing API.\n-   [2] These operations can be initiated using the SDK's public API.\n-   [3] Unsupported operations: creating records for tables which have not yet been loaded,\n    [creating records with data for fields which have not yet been loaded](https://github.com/Hyperbase/blocks-sdk/blob/a77fa4b959f512a041e987ee0bfe3fafb7db8b59/packages/sdk/src/models/mutations.ts#L583),\n    and creating records in specific views\n\n## Key concepts\n\n**Test fixture data** is a representation of the state of an Airtable Base, including descriptions\nof Tables, Views, Fields, and Records. It is written by test authors and in terms of\nJSON-serializable values.\n[The Extension Test Fixtures Airtable Extension](https://airtable.com/marketplace/blk5qI32GYyYb1Rbm/test-fixture-generator)\nallows developers to generate this data from the state of an authentic Base. This Extension is not\nready for beta yet.\n\n**`TestDriver`** is the JavaScript interface for creating and manipulating a simulated Airtable\nExtensions environment. It implements methods for performing operations which are not available in\nthe SDK.\n\n**`AirtableInterface`** is the layer of the SDK which mediates between the models and the backend.\nIn production environments, it operates via asynchronous message passing with the Extension's parent\nweb browser frame. In testing environments, no transmission occurs, but the `AirtableInterface`\nbehaves as though it is receiving relevant messages in order to simulate production behavior.\n\n**Mutations** are instructions which describe changes to the Base. Mutations travel through the\n`AirtableInterface`, which sends them to the backend in production environments only.\n\n## Writing tests\n\nAs of January 2021, Airtable Extensions must be written using the React framework. These\ninstructions take the presence of React for granted.\n\nEvery test file must import TestDriver through the `@airtable/blocks-testing` module to ensure that\nthe environment is correctly instrumented for automation.\n\nEach test will typically perform the following steps:\n\n1.  Create a TestDriver instance, providing valid fixture data:\n\n    ```js\n    const testDriver = new TestDriver({\n        /* fixture data here */\n    });\n    ```\n\n2.  Create an instance of the Extension under test by rendering the Extension's Component as a child\n    of the `TestDriver#Container` Component.\n\n    ```js\n    render(\n        <testDriver.Container>\n            <MyExtension />\n        </testDriver.Container>,\n    );\n    ```\n\n3.  Provide some input to the Extension. This may be in the form of a simulated user interaction\n    (e.g. via\n    [the `@testing-library/user-event` library](https://www.npmjs.com/package/@testing-library/user-event))\n\n    ```js\n    // Simulate a user choosing the \"Gruyere\" option from the table labed\n    // \"Cheeses\".\n    const input = screen.getByLabelText('Cheeses');\n    const option = screen.getByText('Gruyere');\n    userEvent.selectOptions(input, [option]);\n    ```\n\n    ...or a simulated backend behavior (e.g. via\n    [the Blocks SDK](https://airtable.com/developers/apps) or the `TestDriver` API).\n\n    ```js\n    // Invoking `createTableAsync` in a test script simulates the condition\n    // where the Airtable backend reports that a table has been created by\n    // another viewer of the Base.\n    await testDriver.base.createTableAsync('a new table', [\n        {name: 'address', type: FieldType.EMAIL},\n    ]);\n    ```\n\n4.  Verify that the Extension responded to the input as expected. For many kinds of interactions,\n    the Extension's response will be discernible by some change in the UI.\n    [The `@testing-library/react` library](https://www.npmjs.com/package/@testing-library/react) is\n    a good choice for inspecting the state of the user interface.\n\n    ```js\n    // Ensure that the UI updated to display the checkbox as \"checked\"\n    const checkbox = screen.getByRole('checkbox');\n    expect(checkbox.checked).toBe(true);\n    ```\n\n    ...while the `TestDriver` API can be used to verify Extension behaviors which do not influence\n    the UI:\n\n    ```js\n    // Track every time the Extension attempts to expand a record.\n    const recordIds = [];\n    testDriver.watch('expandRecord', ({recordId}) => recordIds.push(recordId));\n\n    // (The code necessary to simulate user inteaction elided from this example.)\n\n    // Ensure that the Extension attempted to expand the Record with ID `reca`\n    expect(recordIds).toEqual(['reca']);\n    ```\n\n[The automated test suite for the To-do List example Extension](https://github.com/Airtable/apps-todo-list/tree/master/test)\ndemonstrates this pattern.\n\n## Extending the Testing API\n\nIn order to provide predictable behavior, the Airtable testing platform relies on simulations of\nBase operations. Every simulation requires some amount of support in the testing platform. Some\nsimulations also require a dedicated testing API.\n\n**Implementing internal support** Every Base operation requires some amount of simulation code in\norder to support scripting in test environments.\n\nFor some operations, this simulation may be as limited as a \"no-op\" implementation of an internal\nmethod. These operations include mutations which the SDK applies optimistically and messages with no\ndirect effect on the Extension.\n\nOther operations will require more advanced simulation logic. Operations of this type generally rely\non the backend's response to determine their effect on the Base. The simulated behavior should be\npredictable, mimicking the expected response in production.\n\n**Implementing a dedicated API** A dedicated testing API is not necessary for any operation which\ncan be expressed through the public API of the SDK (e.g. \"create many records\" or \"delete a table\").\nWhen a test author wishes to script such an operation, they should use the SDK directly. This is\nvalid because an Extension cannot distinguish between operations initiated by the backend and\noperations initiated by a test script using the SDK.\n\nMany other operations cannot be expressed via the public API of the SDK. The `TestDriver` API must\nbe extended to allow test authors to simulate these operations.\n\nSome of these restrictions are circumstantial, owing to the fact that as of January 2021, the SDK is\nincomplete and under active development. This includes an API to delete a Field. Other restrictions\nare fundamental to the design of the Extensions platform. For instance, the SDK intentionally omits\na method for an Extension to change the permissions of the current user. This distinction may inform\nthe decision to introduce a testing API, since doing so will increase maintenance responsibilities\nin a way that may be obviated by future extensions to the SDK's public API.\n","readmeFilename":"README.md"}