diff --git a/Pipfile.lock b/Pipfile.lock index 42b9018172..eca0315c83 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,522 +1,563 @@ { - "_meta": { - "hash": { - "sha256": "55acc4758cdb5f5112921b960586e78aa312e91c0c7aa44478e52763ab2b26ee" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "anys": { - "hashes": [ - "sha256:56c04f76afe5379a5058aec067befa1fb93070d63cabbd342e04b3d5aff739f8", - "sha256:ae4124d98ab0449a457d1563e86c9f9baa059707bf7bd65248d594b1fdc2a5c2" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.3.0" - }, - "icdiff": { - "hashes": [ - "sha256:f05d1b3623223dd1c70f7848da7d699de3d9a2550b902a8234d9026292fb5762", - "sha256:f79a318891adbf59a45e3a7694f5e1f18c5407065264637072ac8363b759866f" - ], - "version": "==2.0.7" - }, - "iniconfig": { - "hashes": [ - "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", - "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" - ], - "markers": "python_version >= '3.8'", - "version": "==2.1.0" - }, - "markupsafe": { - "hashes": [ - "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", - "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", - "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", - "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", - "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", - "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", - "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", - "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", - "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", - "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", - "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", - "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", - "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", - "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", - "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", - "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", - "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", - "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", - "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", - "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", - "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", - "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", - "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", - "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", - "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", - "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", - "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", - "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", - "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", - "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", - "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", - "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", - "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", - "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", - "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", - "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", - "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", - "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", - "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", - "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", - "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", - "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", - "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", - "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", - "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", - "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", - "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", - "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", - "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", - "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", - "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", - "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", - "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", - "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", - "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", - "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", - "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", - "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", - "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", - "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", - "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" - ], - "markers": "python_version >= '3.9'", - "version": "==3.0.2" - }, - "mypy": { - "hashes": [ - "sha256:091f53ff88cb093dcc33c29eee522c087a438df65eb92acd371161c1f4380ff0", - "sha256:1a69db3018b87b3e6e9dd28970f983ea6c933800c9edf8c503c3135b3274d5ad", - "sha256:24f3de8b9e7021cd794ad9dfbf2e9fe3f069ff5e28cb57af6f873ffec1cb0425", - "sha256:31eba8a7a71f0071f55227a8057468b8d2eb5bf578c8502c7f01abaec8141b2f", - "sha256:3c8835a07b8442da900db47ccfda76c92c69c3a575872a5b764332c4bacb5a0a", - "sha256:3df87094028e52766b0a59a3e46481bb98b27986ed6ded6a6cc35ecc75bb9182", - "sha256:49499cf1e464f533fc45be54d20a6351a312f96ae7892d8e9f1708140e27ce41", - "sha256:4c192445899c69f07874dabda7e931b0cc811ea055bf82c1ababf358b9b2a72c", - "sha256:4f3d27537abde1be6d5f2c96c29a454da333a2a271ae7d5bc7110e6d4b7beb3f", - "sha256:7469545380dddce5719e3656b80bdfbb217cfe8dbb1438532d6abc754b828fed", - "sha256:7807a2a61e636af9ca247ba8494031fb060a0a744b9fee7de3a54bed8a753323", - "sha256:856bad61ebc7d21dbc019b719e98303dc6256cec6dcc9ebb0b214b81d6901bd8", - "sha256:89513ddfda06b5c8ebd64f026d20a61ef264e89125dc82633f3c34eeb50e7d60", - "sha256:8e0db37ac4ebb2fee7702767dfc1b773c7365731c22787cb99f507285014fcaf", - "sha256:971104bcb180e4fed0d7bd85504c9036346ab44b7416c75dd93b5c8c6bb7e28f", - "sha256:9e1589ca150a51d9d00bb839bfeca2f7a04f32cd62fad87a847bc0818e15d7dc", - "sha256:9f8464ed410ada641c29f5de3e6716cbdd4f460b31cf755b2af52f2d5ea79ead", - "sha256:ab98b8f6fdf669711f3abe83a745f67f50e3cbaea3998b90e8608d2b459fd566", - "sha256:b19006055dde8a5425baa5f3b57a19fa79df621606540493e5e893500148c72f", - "sha256:c69051274762cccd13498b568ed2430f8d22baa4b179911ad0c1577d336ed849", - "sha256:d2dad072e01764823d4b2f06bc7365bb1d4b6c2f38c4d42fade3c8d45b0b4b67", - "sha256:dccd850a2e3863891871c9e16c54c742dba5470f5120ffed8152956e9e0a5e13", - "sha256:e28d7b221898c401494f3b77db3bac78a03ad0a0fff29a950317d87885c655d2", - "sha256:e4b7a99275a61aa22256bab5839c35fe8a6887781862471df82afb4b445daae6", - "sha256:eb7ff4007865833c470a601498ba30462b7374342580e2346bf7884557e40531", - "sha256:f8598307150b5722854f035d2e70a1ad9cc3c72d392c34fffd8c66d888c90f17", - "sha256:fea451a3125bf0bfe716e5d7ad4b92033c471e4b5b3e154c67525539d14dc15a" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.6.0" - }, - "mypy-extensions": { - "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.0" - }, - "packaging": { - "hashes": [ - "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", - "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" - ], - "markers": "python_version >= '3.8'", - "version": "==24.2" - }, - "pillow": { - "hashes": [ - "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c", - "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2", - "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb", - "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d", - "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa", - "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3", - "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1", - "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a", - "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd", - "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8", - "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999", - "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599", - "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936", - "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375", - "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d", - "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b", - "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60", - "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572", - "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3", - "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced", - "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f", - "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b", - "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19", - "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f", - "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d", - "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383", - "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795", - "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355", - "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57", - "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09", - "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b", - "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462", - "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf", - "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f", - "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a", - "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad", - "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9", - "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d", - "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45", - "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994", - "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d", - "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338", - "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463", - "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451", - "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591", - "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c", - "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd", - "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32", - "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9", - "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf", - "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5", - "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828", - "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3", - "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5", - "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2", - "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b", - "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2", - "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475", - "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3", - "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb", - "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef", - "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015", - "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002", - "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170", - "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84", - "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57", - "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f", - "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27", - "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==10.3.0" - }, - "pluggy": { - "hashes": [ - "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", - "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" - ], - "markers": "python_version >= '3.8'", - "version": "==1.5.0" - }, - "pprintpp": { - "hashes": [ - "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d", - "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403" - ], - "version": "==0.4.0" - }, - "pytest": { - "hashes": [ - "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002", - "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.4.2" - }, - "pytest-asyncio": { - "hashes": [ - "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d", - "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.21.1" - }, - "pytest-httpserver": { - "hashes": [ - "sha256:24cd3d9f6a0b927c7bfc400d0b3fda7442721b8267ce29942bf307b190f0bb09", - "sha256:e052f69bc8a9073db02484681e8e47004dd1fb3763b0ae833bd899e5895c559a" - ], - "index": "pypi", - "markers": "python_version >= '3.8' and python_version < '4.0'", - "version": "==1.0.8" - }, - "pytest-icdiff": { - "hashes": [ - "sha256:4f493ae5ee63c8e90e9f96d4b0b2968b19634dfed8a6e3c9848fcd0d6cadcf7b", - "sha256:8fac8667d7042270c23019580b4b5dfd81e1c3e5a9bc9d5df6ac4a49788d42f2" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.8" - }, - "pytest-repeat": { - "hashes": [ - "sha256:c1738b4e412a6f3b3b9e0b8b29fcd7a423e50f87381ad9307ef6f5a8601139f3", - "sha256:d92ac14dfaa6ffcfe6917e5d16f0c9bc82380c135b03c2a5f412d2637f224485" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==0.9.4" - }, - "pytest-rerunfailures": { - "hashes": [ - "sha256:784f462fa87fe9bdf781d0027d856b47a4bfe6c12af108f6bd887057a917b48e", - "sha256:9a1afd04e21b8177faf08a9bbbf44de7a0fe3fc29f8ddbe83b9684bd5f8f92a9" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==12.0" - }, - "pytest-shard": { - "hashes": [ - "sha256:407a1df385cebe1feb9b4d2e7eeee8b044f8a24f0919421233159a17c59be2b9", - "sha256:b86a967fbfd1c8e50295095ccda031b7e890862ee06531d5142844f4c1d1cd67" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==0.1.2" - }, - "pytest-timeout": { - "hashes": [ - "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90", - "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.2.0" - }, - "syrupy": { - "hashes": [ - "sha256:6e01fccb4cd5ad37ce54e8c265cde068fa9c37b7a0946c603c328e8a38a7330d", - "sha256:ea6a237ef374bacebbdb4049f73bf48e3dda76eabd4621a6d104d43077529de6" - ], - "index": "pypi", - "markers": "python_version < '4' and python_full_version >= '3.8.1'", - "version": "==4.5.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", - "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" - ], - "markers": "python_version >= '3.8'", - "version": "==4.13.2" - }, - "websockets": { - "hashes": [ - "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd", - "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f", - "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998", - "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82", - "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788", - "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa", - "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f", - "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4", - "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7", - "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f", - "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd", - "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69", - "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb", - "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b", - "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016", - "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac", - "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4", - "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb", - "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99", - "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e", - "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54", - "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf", - "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007", - "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3", - "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6", - "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86", - "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1", - "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61", - "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11", - "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8", - "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f", - "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931", - "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526", - "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016", - "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae", - "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd", - "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b", - "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311", - "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af", - "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152", - "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288", - "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de", - "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97", - "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d", - "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d", - "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca", - "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0", - "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9", - "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b", - "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e", - "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128", - "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d", - "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c", - "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5", - "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6", - "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b", - "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b", - "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280", - "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c", - "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c", - "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f", - "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20", - "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8", - "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb", - "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602", - "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf", - "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0", - "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74", - "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0", - "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==11.0.3" - }, - "werkzeug": { - "hashes": [ - "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", - "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746" - ], - "markers": "python_version >= '3.9'", - "version": "==3.1.3" - } - }, - "develop": { - "execnet": { - "hashes": [ - "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", - "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3" - ], - "markers": "python_version >= '3.8'", - "version": "==2.1.1" - }, - "iniconfig": { - "hashes": [ - "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", - "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" - ], - "markers": "python_version >= '3.8'", - "version": "==2.1.0" - }, - "packaging": { - "hashes": [ - "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", - "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" - ], - "markers": "python_version >= '3.8'", - "version": "==24.2" - }, - "pluggy": { - "hashes": [ - "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", - "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" - ], - "markers": "python_version >= '3.8'", - "version": "==1.5.0" - }, - "pyflakes": { - "hashes": [ - "sha256:5039c8339cbb1944045f4ee5466908906180f13cc99cc9949348d10f82a5c32a", - "sha256:6dfd61d87b97fba5dcfaaf781171ac16be16453be6d816147989e7f6e6a9576b" - ], - "markers": "python_version >= '3.9'", - "version": "==3.3.2" - }, - "pytest": { - "hashes": [ - "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002", - "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.4.2" - }, - "pytest-flakefinder": { - "hashes": [ - "sha256:741e0e8eea427052f5b8c89c2b3c3019a50c39a59ce4df6a305a2c2d9ba2bd13", - "sha256:e2412a1920bdb8e7908783b20b3d57e9dad590cc39a93e8596ffdd493b403e0e" - ], - "index": "pypi", - "markers": "python_version >= '3.5'", - "version": "==1.1.0" - }, - "pytest-flakes": { - "hashes": [ - "sha256:953134e97215ae31f6879fbd7368c18d43f709dc2fab5b7777db2bb2bac3a924", - "sha256:d0e8602d882744fc6169247b62a51203c5a3d8f160892ff3b82f5b9c1e4bb675" - ], - "index": "pypi", - "markers": "python_version >= '3.5'", - "version": "==4.0.5" - }, - "pytest-instafail": { - "hashes": [ - "sha256:33a606f7e0c8e646dc3bfee0d5e3a4b7b78ef7c36168cfa1f3d93af7ca706c9e", - "sha256:6855414487e9e4bb76a118ce952c3c27d3866af15487506c4ded92eb72387819" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.5.0" - }, - "pytest-randomly": { - "hashes": [ - "sha256:11bf4d23a26484de7860d82f726c0629837cf4064b79157bd18ec9d41d7feb26", - "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==3.16.0" - }, - "pytest-xdist": { - "hashes": [ - "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", - "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.6.1" + "_meta": { + "hash": { + "sha256": "eb87d19f8fffc9adc2be32b619b6737795b1058194822d52bb3a60033d3a028a" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "anys": { + "hashes": [ + "sha256:56c04f76afe5379a5058aec067befa1fb93070d63cabbd342e04b3d5aff739f8", + "sha256:ae4124d98ab0449a457d1563e86c9f9baa059707bf7bd65248d594b1fdc2a5c2" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.3.0" + }, + "blinker": { + "hashes": [ + "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", + "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc" + ], + "markers": "python_version >= '3.9'", + "version": "==1.9.0" + }, + "click": { + "hashes": [ + "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", + "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b" + ], + "markers": "python_version >= '3.10'", + "version": "==8.2.1" + }, + "flask": { + "hashes": [ + "sha256:07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c", + "sha256:284c7b8f2f58cb737f0cf1c30fd7eaf0ccfcde196099d24ecede3fc2005aa59e" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.1.1" + }, + "icdiff": { + "hashes": [ + "sha256:f05d1b3623223dd1c70f7848da7d699de3d9a2550b902a8234d9026292fb5762", + "sha256:f79a318891adbf59a45e3a7694f5e1f18c5407065264637072ac8363b759866f" + ], + "version": "==2.0.7" + }, + "iniconfig": { + "hashes": [ + "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", + "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" + ], + "markers": "python_version >= '3.8'", + "version": "==2.1.0" + }, + "itsdangerous": { + "hashes": [ + "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", + "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.0" + }, + "jinja2": { + "hashes": [ + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.6" + }, + "markupsafe": { + "hashes": [ + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" + ], + "markers": "python_version >= '3.9'", + "version": "==3.0.2" + }, + "mypy": { + "hashes": [ + "sha256:091f53ff88cb093dcc33c29eee522c087a438df65eb92acd371161c1f4380ff0", + "sha256:1a69db3018b87b3e6e9dd28970f983ea6c933800c9edf8c503c3135b3274d5ad", + "sha256:24f3de8b9e7021cd794ad9dfbf2e9fe3f069ff5e28cb57af6f873ffec1cb0425", + "sha256:31eba8a7a71f0071f55227a8057468b8d2eb5bf578c8502c7f01abaec8141b2f", + "sha256:3c8835a07b8442da900db47ccfda76c92c69c3a575872a5b764332c4bacb5a0a", + "sha256:3df87094028e52766b0a59a3e46481bb98b27986ed6ded6a6cc35ecc75bb9182", + "sha256:49499cf1e464f533fc45be54d20a6351a312f96ae7892d8e9f1708140e27ce41", + "sha256:4c192445899c69f07874dabda7e931b0cc811ea055bf82c1ababf358b9b2a72c", + "sha256:4f3d27537abde1be6d5f2c96c29a454da333a2a271ae7d5bc7110e6d4b7beb3f", + "sha256:7469545380dddce5719e3656b80bdfbb217cfe8dbb1438532d6abc754b828fed", + "sha256:7807a2a61e636af9ca247ba8494031fb060a0a744b9fee7de3a54bed8a753323", + "sha256:856bad61ebc7d21dbc019b719e98303dc6256cec6dcc9ebb0b214b81d6901bd8", + "sha256:89513ddfda06b5c8ebd64f026d20a61ef264e89125dc82633f3c34eeb50e7d60", + "sha256:8e0db37ac4ebb2fee7702767dfc1b773c7365731c22787cb99f507285014fcaf", + "sha256:971104bcb180e4fed0d7bd85504c9036346ab44b7416c75dd93b5c8c6bb7e28f", + "sha256:9e1589ca150a51d9d00bb839bfeca2f7a04f32cd62fad87a847bc0818e15d7dc", + "sha256:9f8464ed410ada641c29f5de3e6716cbdd4f460b31cf755b2af52f2d5ea79ead", + "sha256:ab98b8f6fdf669711f3abe83a745f67f50e3cbaea3998b90e8608d2b459fd566", + "sha256:b19006055dde8a5425baa5f3b57a19fa79df621606540493e5e893500148c72f", + "sha256:c69051274762cccd13498b568ed2430f8d22baa4b179911ad0c1577d336ed849", + "sha256:d2dad072e01764823d4b2f06bc7365bb1d4b6c2f38c4d42fade3c8d45b0b4b67", + "sha256:dccd850a2e3863891871c9e16c54c742dba5470f5120ffed8152956e9e0a5e13", + "sha256:e28d7b221898c401494f3b77db3bac78a03ad0a0fff29a950317d87885c655d2", + "sha256:e4b7a99275a61aa22256bab5839c35fe8a6887781862471df82afb4b445daae6", + "sha256:eb7ff4007865833c470a601498ba30462b7374342580e2346bf7884557e40531", + "sha256:f8598307150b5722854f035d2e70a1ad9cc3c72d392c34fffd8c66d888c90f17", + "sha256:fea451a3125bf0bfe716e5d7ad4b92033c471e4b5b3e154c67525539d14dc15a" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.6.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", + "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" + ], + "markers": "python_version >= '3.8'", + "version": "==1.1.0" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pillow": { + "hashes": [ + "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c", + "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2", + "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb", + "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d", + "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa", + "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3", + "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1", + "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a", + "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd", + "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8", + "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999", + "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599", + "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936", + "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375", + "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d", + "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b", + "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60", + "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572", + "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3", + "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced", + "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f", + "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b", + "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19", + "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f", + "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d", + "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383", + "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795", + "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355", + "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57", + "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09", + "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b", + "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462", + "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf", + "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f", + "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a", + "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad", + "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9", + "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d", + "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45", + "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994", + "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d", + "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338", + "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463", + "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451", + "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591", + "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c", + "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd", + "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32", + "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9", + "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf", + "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5", + "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828", + "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3", + "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5", + "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2", + "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b", + "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2", + "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475", + "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3", + "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb", + "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef", + "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015", + "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002", + "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170", + "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84", + "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57", + "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f", + "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27", + "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==10.3.0" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, + "pprintpp": { + "hashes": [ + "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d", + "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403" + ], + "version": "==0.4.0" + }, + "pytest": { + "hashes": [ + "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002", + "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==7.4.2" + }, + "pytest-asyncio": { + "hashes": [ + "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d", + "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.21.1" + }, + "pytest-httpserver": { + "hashes": [ + "sha256:24cd3d9f6a0b927c7bfc400d0b3fda7442721b8267ce29942bf307b190f0bb09", + "sha256:e052f69bc8a9073db02484681e8e47004dd1fb3763b0ae833bd899e5895c559a" + ], + "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==1.0.8" + }, + "pytest-icdiff": { + "hashes": [ + "sha256:4f493ae5ee63c8e90e9f96d4b0b2968b19634dfed8a6e3c9848fcd0d6cadcf7b", + "sha256:8fac8667d7042270c23019580b4b5dfd81e1c3e5a9bc9d5df6ac4a49788d42f2" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.8" + }, + "pytest-repeat": { + "hashes": [ + "sha256:c1738b4e412a6f3b3b9e0b8b29fcd7a423e50f87381ad9307ef6f5a8601139f3", + "sha256:d92ac14dfaa6ffcfe6917e5d16f0c9bc82380c135b03c2a5f412d2637f224485" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==0.9.4" + }, + "pytest-rerunfailures": { + "hashes": [ + "sha256:784f462fa87fe9bdf781d0027d856b47a4bfe6c12af108f6bd887057a917b48e", + "sha256:9a1afd04e21b8177faf08a9bbbf44de7a0fe3fc29f8ddbe83b9684bd5f8f92a9" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==12.0" + }, + "pytest-shard": { + "hashes": [ + "sha256:407a1df385cebe1feb9b4d2e7eeee8b044f8a24f0919421233159a17c59be2b9", + "sha256:b86a967fbfd1c8e50295095ccda031b7e890862ee06531d5142844f4c1d1cd67" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==0.1.2" + }, + "pytest-timeout": { + "hashes": [ + "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90", + "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==2.2.0" + }, + "syrupy": { + "hashes": [ + "sha256:6e01fccb4cd5ad37ce54e8c265cde068fa9c37b7a0946c603c328e8a38a7330d", + "sha256:ea6a237ef374bacebbdb4049f73bf48e3dda76eabd4621a6d104d43077529de6" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.1' and python_version < '4'", + "version": "==4.5.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + ], + "markers": "python_version >= '3.9'", + "version": "==4.15.0" + }, + "websockets": { + "hashes": [ + "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd", + "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f", + "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998", + "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82", + "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788", + "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa", + "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f", + "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4", + "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7", + "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f", + "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd", + "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69", + "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb", + "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b", + "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016", + "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac", + "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4", + "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb", + "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99", + "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e", + "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54", + "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf", + "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007", + "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3", + "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6", + "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86", + "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1", + "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61", + "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11", + "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8", + "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f", + "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931", + "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526", + "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016", + "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae", + "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd", + "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b", + "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311", + "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af", + "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152", + "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288", + "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de", + "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97", + "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d", + "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d", + "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca", + "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0", + "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9", + "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b", + "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e", + "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128", + "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d", + "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c", + "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5", + "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6", + "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b", + "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b", + "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280", + "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c", + "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c", + "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f", + "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20", + "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8", + "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb", + "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602", + "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf", + "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0", + "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74", + "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0", + "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==11.0.3" + }, + "werkzeug": { + "hashes": [ + "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", + "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746" + ], + "markers": "python_version >= '3.9'", + "version": "==3.1.3" + } + }, + "develop": { + "execnet": { + "hashes": [ + "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", + "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3" + ], + "markers": "python_version >= '3.8'", + "version": "==2.1.1" + }, + "iniconfig": { + "hashes": [ + "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", + "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" + ], + "markers": "python_version >= '3.8'", + "version": "==2.1.0" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, + "pyflakes": { + "hashes": [ + "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", + "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" + ], + "markers": "python_version >= '3.9'", + "version": "==3.4.0" + }, + "pytest": { + "hashes": [ + "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002", + "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==7.4.2" + }, + "pytest-flakefinder": { + "hashes": [ + "sha256:741e0e8eea427052f5b8c89c2b3c3019a50c39a59ce4df6a305a2c2d9ba2bd13", + "sha256:e2412a1920bdb8e7908783b20b3d57e9dad590cc39a93e8596ffdd493b403e0e" + ], + "index": "pypi", + "markers": "python_version >= '3.5'", + "version": "==1.1.0" + }, + "pytest-flakes": { + "hashes": [ + "sha256:953134e97215ae31f6879fbd7368c18d43f709dc2fab5b7777db2bb2bac3a924", + "sha256:d0e8602d882744fc6169247b62a51203c5a3d8f160892ff3b82f5b9c1e4bb675" + ], + "index": "pypi", + "markers": "python_version >= '3.5'", + "version": "==4.0.5" + }, + "pytest-instafail": { + "hashes": [ + "sha256:33a606f7e0c8e646dc3bfee0d5e3a4b7b78ef7c36168cfa1f3d93af7ca706c9e", + "sha256:6855414487e9e4bb76a118ce952c3c27d3866af15487506c4ded92eb72387819" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.5.0" + }, + "pytest-randomly": { + "hashes": [ + "sha256:11bf4d23a26484de7860d82f726c0629837cf4064b79157bd18ec9d41d7feb26", + "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.16.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", + "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.8.0" + } } - } } diff --git a/src/bidiMapper/BidiNoOpParser.ts b/src/bidiMapper/BidiNoOpParser.ts index 96dfe5d1aa..1fc7d01493 100644 --- a/src/bidiMapper/BidiNoOpParser.ts +++ b/src/bidiMapper/BidiNoOpParser.ts @@ -16,6 +16,7 @@ */ import type { + Autofill, Browser, BrowsingContext, Cdp, @@ -33,6 +34,13 @@ import type { import type {BidiCommandParameterParser} from './BidiParser.js'; export class BidiNoOpParser implements BidiCommandParameterParser { + // Autofill module + // keep-sorted start block=yes + parseAutofillTriggerParams(params: unknown): Autofill.TriggerParameters { + return params as Autofill.TriggerParameters; + } + // keep-sorted end + // Bluetooth module // keep-sorted start block=yes parseDisableSimulationParameters( diff --git a/src/bidiMapper/BidiParser.ts b/src/bidiMapper/BidiParser.ts index 83c85e933c..93231d1efd 100644 --- a/src/bidiMapper/BidiParser.ts +++ b/src/bidiMapper/BidiParser.ts @@ -16,6 +16,7 @@ */ import type { + Autofill, Bluetooth, Browser, BrowsingContext, @@ -31,6 +32,11 @@ import type { } from '../protocol/protocol.js'; export interface BidiCommandParameterParser { + // Autofill module + // keep-sorted start block=yes + parseAutofillTriggerParams(params: unknown): Autofill.TriggerParameters; + // keep-sorted end + // Bluetooth module // keep-sorted start block=yes parseDisableSimulationParameters( diff --git a/src/bidiMapper/CommandProcessor.ts b/src/bidiMapper/CommandProcessor.ts index bbda9760f1..9d08d46471 100644 --- a/src/bidiMapper/CommandProcessor.ts +++ b/src/bidiMapper/CommandProcessor.ts @@ -32,6 +32,7 @@ import type {Result} from '../utils/result.js'; import {BidiNoOpParser} from './BidiNoOpParser.js'; import type {BidiCommandParameterParser} from './BidiParser.js'; import type {MapperOptions} from './MapperOptions.js'; +import {AutofillProcessor} from './modules/autofill/AutofillProcessor.js'; import type {BluetoothProcessor} from './modules/bluetooth/BluetoothProcessor.js'; import {BrowserProcessor} from './modules/browser/BrowserProcessor.js'; import type {ContextConfigStorage} from './modules/browser/ContextConfigStorage.js'; @@ -66,6 +67,7 @@ interface CommandProcessorEventsMap extends Record { export class CommandProcessor extends EventEmitter { // keep-sorted start + #autofillProcessor: AutofillProcessor; #bluetoothProcessor: BluetoothProcessor; #browserCdpClient: CdpClient; #browserProcessor: BrowserProcessor; @@ -105,6 +107,7 @@ export class CommandProcessor extends EventEmitter { this.#logger = logger; this.#bluetoothProcessor = bluetoothProcessor; + this.#autofillProcessor = new AutofillProcessor(browsingContextStorage); // keep-sorted start block=yes this.#browserProcessor = new BrowserProcessor( @@ -165,8 +168,17 @@ export class CommandProcessor extends EventEmitter { command: ChromiumBidi.Command, ): Promise { switch (command.method) { + // Autofill module + // keep-sorted start block=yes + case 'autofill.trigger': + return await this.#autofillProcessor.trigger( + this.#parser.parseAutofillTriggerParams(command.params), + ); + // keep-sorted end + // Bluetooth module // keep-sorted start block=yes + case 'bluetooth.disableSimulation': return await this.#bluetoothProcessor.disableSimulation( this.#parser.parseDisableSimulationParameters(command.params), diff --git a/src/bidiMapper/modules/autofill/AutofillProcessor.ts b/src/bidiMapper/modules/autofill/AutofillProcessor.ts new file mode 100644 index 0000000000..077cf2150f --- /dev/null +++ b/src/bidiMapper/modules/autofill/AutofillProcessor.ts @@ -0,0 +1,104 @@ +/** + * Copyright 2025 Google LLC. + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type {CdpClient} from '../../../cdp/CdpClient.js'; +import { + type Autofill, + type EmptyResult, + NoSuchNodeException, + UnsupportedOperationException, +} from '../../../protocol/protocol.js'; +import type {BrowsingContextStorage} from '../context/BrowsingContextStorage.js'; +import {parseSharedId} from '../script/SharedId.js'; + +/** + * Responsible for handling the `autofill` module. + */ +export class AutofillProcessor { + readonly #browsingContextStorage: BrowsingContextStorage; + + constructor(browsingContextStorage: BrowsingContextStorage) { + this.#browsingContextStorage = browsingContextStorage; + } + + /** + * Triggers autofill for a specific element with the provided field data. + * + * @param params Parameters for the autofill.trigger command + * @returns An empty result + */ + async trigger(params: Autofill.TriggerParameters): Promise { + try { + // Get the browsing context from the parameters + const context = this.#browsingContextStorage.getContext(params.context); + + // Parse the shared ID to get frame, document, and backend node ID + const parsedSharedId = parseSharedId(params.element.sharedId); + if (parsedSharedId === null) { + throw new NoSuchNodeException( + `SharedId "${params.element.sharedId}" was not found.`, + ); + } + + const {frameId, documentId, backendNodeId} = parsedSharedId; + + // Assert that the frame matches the current context (if frameId is available) + if (frameId !== undefined && frameId !== params.context) { + throw new NoSuchNodeException( + `SharedId "${params.element.sharedId}" belongs to different frame. Current frame is ${params.context}.`, + ); + } + + // Assert that the document matches the current context's navigable ID + if (context.navigableId !== documentId) { + throw new NoSuchNodeException( + `SharedId "${params.element.sharedId}" belongs to different document. Current document is ${context.navigableId}.`, + ); + } + + // Cast to `any` as a temporary workaround for prototyping, since the TypeScript types + // for CDP in "Chromium BiDi" aren't automatically updated with local changes. + + // Based on the Autofill.pdl definition, call the correct CDP method + // The PDL shows: command trigger with fieldId as DOM.BackendNodeId + + // First, we need to enable the Autofill domain + try { + await context.cdpTarget.cdpClient.sendCommand('Autofill.enable'); + } catch (enableErr) { + console.log('Failed to enable Autofill domain:', (enableErr as Error).message); + } + + // Call the trigger method with the correct parameters from PDL + await (context.cdpTarget.cdpClient as any).sendCommand('Autofill.trigger', { + fieldId: backendNodeId, // DOM.BackendNodeId from parsed shared ID + frameId: frameId, // Page.FrameId from parsed shared ID + card: params.card, // optional CreditCard + address: params.address, // optional Address + }); + + return {}; + } catch (err) { + if ((err as Error).message.includes('command was not found')) { + throw new UnsupportedOperationException( + 'Autofill.trigger() is not supported by this browser', + ); + } + throw err; + } + } +} diff --git a/src/bidiTab/BidiParser.ts b/src/bidiTab/BidiParser.ts index e55993efeb..e00055f944 100644 --- a/src/bidiTab/BidiParser.ts +++ b/src/bidiTab/BidiParser.ts @@ -16,6 +16,7 @@ */ import type {BidiCommandParameterParser} from '../bidiMapper/BidiMapper.js'; import type { + Autofill, Bluetooth, Browser, BrowsingContext, @@ -32,6 +33,13 @@ import type { import * as Parser from '../protocol-parser/protocol-parser.js'; export class BidiParser implements BidiCommandParameterParser { + // Autofill module + // keep-sorted start block=yes + parseAutofillTriggerParams(params: unknown): Autofill.TriggerParameters { + return Parser.Autofill.parseTriggerParameters(params); + } + // keep-sorted end + // Bluetooth module // keep-sorted start block=yes parseDisableSimulationParameters( diff --git a/src/protocol-parser/generated/webdriver-bidi.ts b/src/protocol-parser/generated/webdriver-bidi.ts index e1baaf10d1..11bd177eb8 100644 --- a/src/protocol-parser/generated/webdriver-bidi.ts +++ b/src/protocol-parser/generated/webdriver-bidi.ts @@ -16,7 +16,7 @@ */ /** - * THIS FILE IS AUTOGENERATED by cddlconv 0.1.7. + * THIS FILE IS AUTOGENERATED by cddlconv 0.1.6. * Run `node tools/generate-bidi-types.mjs` to regenerate. * @see https://github.com/w3c/webdriver-bidi/blob/master/index.bs */ @@ -26,6 +26,14 @@ import z from 'zod'; +export const EventSchema = z.lazy(() => + z + .object({ + type: z.literal('event'), + }) + .and(EventDataSchema) + .and(ExtensibleSchema), +); export const CommandSchema = z.lazy(() => z .object({ @@ -34,6 +42,24 @@ export const CommandSchema = z.lazy(() => .and(CommandDataSchema) .and(ExtensibleSchema), ); +export const CommandResponseSchema = z.lazy(() => + z + .object({ + type: z.literal('success'), + id: JsUintSchema, + result: ResultDataSchema, + }) + .and(ExtensibleSchema), +); +export const EventDataSchema = z.lazy(() => + z.union([ + BrowsingContextEventSchema, + InputEventSchema, + LogEventSchema, + NetworkEventSchema, + ScriptEventSchema, + ]), +); export const CommandDataSchema = z.lazy(() => z.union([ BrowserCommandSchema, @@ -45,32 +71,9 @@ export const CommandDataSchema = z.lazy(() => SessionCommandSchema, StorageCommandSchema, WebExtensionCommandSchema, + AutofillCommandSchema, ]), ); -export const EmptyParamsSchema = z.lazy(() => ExtensibleSchema); -export const MessageSchema = z.lazy(() => - z.union([CommandResponseSchema, ErrorResponseSchema, EventSchema]), -); -export const CommandResponseSchema = z.lazy(() => - z - .object({ - type: z.literal('success'), - id: JsUintSchema, - result: ResultDataSchema, - }) - .and(ExtensibleSchema), -); -export const ErrorResponseSchema = z.lazy(() => - z - .object({ - type: z.literal('error'), - id: z.union([JsUintSchema, z.null()]), - error: ErrorCodeSchema, - message: z.string(), - stacktrace: z.string().optional(), - }) - .and(ExtensibleSchema), -); export const ResultDataSchema = z.lazy(() => z.union([ BrowsingContextResultSchema, @@ -82,24 +85,22 @@ export const ResultDataSchema = z.lazy(() => WebExtensionResultSchema, ]), ); -export const EmptyResultSchema = z.lazy(() => ExtensibleSchema); -export const EventSchema = z.lazy(() => +export const EmptyParamsSchema = z.lazy(() => ExtensibleSchema); +export const MessageSchema = z.lazy(() => + z.union([CommandResponseSchema, ErrorResponseSchema, EventSchema]), +); +export const ErrorResponseSchema = z.lazy(() => z .object({ - type: z.literal('event'), + type: z.literal('error'), + id: z.union([JsUintSchema, z.null()]), + error: ErrorCodeSchema, + message: z.string(), + stacktrace: z.string().optional(), }) - .and(EventDataSchema) .and(ExtensibleSchema), ); -export const EventDataSchema = z.lazy(() => - z.union([ - BrowsingContextEventSchema, - InputEventSchema, - LogEventSchema, - NetworkEventSchema, - ScriptEventSchema, - ]), -); +export const EmptyResultSchema = z.lazy(() => ExtensibleSchema); export const ExtensibleSchema = z.lazy(() => z.record(z.string(), z.any())); export const JsIntSchema = z .number() @@ -116,6 +117,7 @@ export const ErrorCodeSchema = z.lazy(() => z.enum([ 'invalid argument', 'invalid selector', + 'invalid element state', 'invalid session id', 'invalid web extension', 'move target out of bounds', @@ -154,6 +156,17 @@ export const SessionCommandSchema = z.lazy(() => Session.UnsubscribeSchema, ]), ); +export namespace Session { + export const ProxyConfigurationSchema = z.lazy(() => + z.union([ + Session.AutodetectProxyConfigurationSchema, + Session.DirectProxyConfigurationSchema, + Session.ManualProxyConfigurationSchema, + Session.PacProxyConfigurationSchema, + Session.SystemProxyConfigurationSchema, + ]), + ); +} export const SessionResultSchema = z.lazy(() => z.union([ Session.NewResultSchema, @@ -183,17 +196,6 @@ export namespace Session { .and(ExtensibleSchema), ); } -export namespace Session { - export const ProxyConfigurationSchema = z.lazy(() => - z.union([ - Session.AutodetectProxyConfigurationSchema, - Session.DirectProxyConfigurationSchema, - Session.ManualProxyConfigurationSchema, - Session.PacProxyConfigurationSchema, - Session.SystemProxyConfigurationSchema, - ]), - ); -} export namespace Session { export const AutodetectProxyConfigurationSchema = z.lazy(() => z @@ -569,17 +571,6 @@ export const BrowsingContextCommandSchema = z.lazy(() => BrowsingContext.TraverseHistorySchema, ]), ); -export const BrowsingContextResultSchema = z.lazy(() => - z.union([ - BrowsingContext.CaptureScreenshotResultSchema, - BrowsingContext.CreateResultSchema, - BrowsingContext.GetTreeResultSchema, - BrowsingContext.LocateNodesResultSchema, - BrowsingContext.NavigateResultSchema, - BrowsingContext.PrintResultSchema, - BrowsingContext.TraverseHistoryResultSchema, - ]), -); export const BrowsingContextEventSchema = z.lazy(() => z.union([ BrowsingContext.ContextCreatedSchema, @@ -598,6 +589,17 @@ export const BrowsingContextEventSchema = z.lazy(() => BrowsingContext.UserPromptOpenedSchema, ]), ); +export const BrowsingContextResultSchema = z.lazy(() => + z.union([ + BrowsingContext.CaptureScreenshotResultSchema, + BrowsingContext.CreateResultSchema, + BrowsingContext.GetTreeResultSchema, + BrowsingContext.LocateNodesResultSchema, + BrowsingContext.NavigateResultSchema, + BrowsingContext.PrintResultSchema, + BrowsingContext.TraverseHistoryResultSchema, + ]), +); export namespace BrowsingContext { export const BrowsingContextSchema = z.lazy(() => z.string()); } @@ -726,14 +728,6 @@ export namespace BrowsingContext { }), ); } -export namespace BrowsingContext { - export const CaptureScreenshotSchema = z.lazy(() => - z.object({ - method: z.literal('browsingContext.captureScreenshot'), - params: BrowsingContext.CaptureScreenshotParametersSchema, - }), - ); -} export namespace BrowsingContext { export const CaptureScreenshotParametersSchema = z.lazy(() => z.object({ @@ -744,6 +738,14 @@ export namespace BrowsingContext { }), ); } +export namespace BrowsingContext { + export const CaptureScreenshotSchema = z.lazy(() => + z.object({ + method: z.literal('browsingContext.captureScreenshot'), + params: BrowsingContext.CaptureScreenshotParametersSchema, + }), + ); +} export namespace BrowsingContext { export const ImageFormatSchema = z.lazy(() => z.object({ @@ -870,14 +872,6 @@ export namespace BrowsingContext { }), ); } -export namespace BrowsingContext { - export const LocateNodesSchema = z.lazy(() => - z.object({ - method: z.literal('browsingContext.locateNodes'), - params: BrowsingContext.LocateNodesParametersSchema, - }), - ); -} export namespace BrowsingContext { export const LocateNodesParametersSchema = z.lazy(() => z.object({ @@ -889,6 +883,14 @@ export namespace BrowsingContext { }), ); } +export namespace BrowsingContext { + export const LocateNodesSchema = z.lazy(() => + z.object({ + method: z.literal('browsingContext.locateNodes'), + params: BrowsingContext.LocateNodesParametersSchema, + }), + ); +} export namespace BrowsingContext { export const LocateNodesResultSchema = z.lazy(() => z.object({ @@ -1423,9 +1425,6 @@ export const NetworkCommandSchema = z.lazy(() => Network.SetExtraHeadersSchema, ]), ); -export const NetworkResultSchema = z.lazy( - () => Network.AddInterceptResultSchema, -); export const NetworkEventSchema = z.lazy(() => z.union([ Network.AuthRequiredSchema, @@ -1435,6 +1434,9 @@ export const NetworkEventSchema = z.lazy(() => Network.ResponseStartedSchema, ]), ); +export const NetworkResultSchema = z.lazy( + () => Network.AddInterceptResultSchema, +); export namespace Network { export const AuthChallengeSchema = z.lazy(() => z.object({ @@ -1679,14 +1681,6 @@ export namespace Network { }), ); } -export namespace Network { - export const AddInterceptSchema = z.lazy(() => - z.object({ - method: z.literal('network.addIntercept'), - params: Network.AddInterceptParametersSchema, - }), - ); -} export namespace Network { export const AddInterceptParametersSchema = z.lazy(() => z.object({ @@ -1699,6 +1693,14 @@ export namespace Network { }), ); } +export namespace Network { + export const AddInterceptSchema = z.lazy(() => + z.object({ + method: z.literal('network.addIntercept'), + params: Network.AddInterceptParametersSchema, + }), + ); +} export namespace Network { export const InterceptPhaseSchema = z.lazy(() => z.enum(['beforeRequestSent', 'responseStarted', 'authRequired']), @@ -1934,14 +1936,13 @@ export namespace Network { }), ); } -export namespace Network { - export const AuthRequiredSchema = z.lazy(() => - z.object({ - method: z.literal('network.authRequired'), - params: Network.AuthRequiredParametersSchema, - }), - ); -} +export const ScriptEventSchema = z.lazy(() => + z.union([ + Script.MessageSchema, + Script.RealmCreatedSchema, + Script.RealmDestroyedSchema, + ]), +); export namespace Network { export const AuthRequiredParametersSchema = z.lazy(() => Network.BaseParametersSchema.and( @@ -1951,14 +1952,6 @@ export namespace Network { ), ); } -export namespace Network { - export const BeforeRequestSentSchema = z.lazy(() => - z.object({ - method: z.literal('network.beforeRequestSent'), - params: Network.BeforeRequestSentParametersSchema, - }), - ); -} export namespace Network { export const BeforeRequestSentParametersSchema = z.lazy(() => Network.BaseParametersSchema.and( @@ -1968,14 +1961,6 @@ export namespace Network { ), ); } -export namespace Network { - export const FetchErrorSchema = z.lazy(() => - z.object({ - method: z.literal('network.fetchError'), - params: Network.FetchErrorParametersSchema, - }), - ); -} export namespace Network { export const FetchErrorParametersSchema = z.lazy(() => Network.BaseParametersSchema.and( @@ -1985,14 +1970,6 @@ export namespace Network { ), ); } -export namespace Network { - export const ResponseCompletedSchema = z.lazy(() => - z.object({ - method: z.literal('network.responseCompleted'), - params: Network.ResponseCompletedParametersSchema, - }), - ); -} export namespace Network { export const ResponseCompletedParametersSchema = z.lazy(() => Network.BaseParametersSchema.and( @@ -2002,14 +1979,6 @@ export namespace Network { ), ); } -export namespace Network { - export const ResponseStartedSchema = z.lazy(() => - z.object({ - method: z.literal('network.responseStarted'), - params: Network.ResponseStartedParametersSchema, - }), - ); -} export namespace Network { export const ResponseStartedParametersSchema = z.lazy(() => Network.BaseParametersSchema.and( @@ -2036,55 +2005,54 @@ export const ScriptResultSchema = z.lazy(() => Script.GetRealmsResultSchema, ]), ); -export const ScriptEventSchema = z.lazy(() => - z.union([ - Script.MessageSchema, - Script.RealmCreatedSchema, - Script.RealmDestroyedSchema, - ]), -); -export namespace Script { - export const ChannelSchema = z.lazy(() => z.string()); +export namespace Network { + export const AuthRequiredSchema = z.lazy(() => + z.object({ + method: z.literal('network.authRequired'), + params: Network.AuthRequiredParametersSchema, + }), + ); } -export namespace Script { - export const ChannelValueSchema = z.lazy(() => +export namespace Network { + export const BeforeRequestSentSchema = z.lazy(() => z.object({ - type: z.literal('channel'), - value: Script.ChannelPropertiesSchema, + method: z.literal('network.beforeRequestSent'), + params: Network.BeforeRequestSentParametersSchema, }), ); } -export namespace Script { - export const ChannelPropertiesSchema = z.lazy(() => +export namespace Network { + export const FetchErrorSchema = z.lazy(() => z.object({ - channel: Script.ChannelSchema, - serializationOptions: Script.SerializationOptionsSchema.optional(), - ownership: Script.ResultOwnershipSchema.optional(), + method: z.literal('network.fetchError'), + params: Network.FetchErrorParametersSchema, }), ); } -export namespace Script { - export const EvaluateResultSchema = z.lazy(() => - z.union([ - Script.EvaluateResultSuccessSchema, - Script.EvaluateResultExceptionSchema, - ]), +export namespace Network { + export const ResponseCompletedSchema = z.lazy(() => + z.object({ + method: z.literal('network.responseCompleted'), + params: Network.ResponseCompletedParametersSchema, + }), ); } -export namespace Script { - export const EvaluateResultSuccessSchema = z.lazy(() => +export namespace Network { + export const ResponseStartedSchema = z.lazy(() => z.object({ - type: z.literal('success'), - result: Script.RemoteValueSchema, - realm: Script.RealmSchema, + method: z.literal('network.responseStarted'), + params: Network.ResponseStartedParametersSchema, }), ); } export namespace Script { - export const EvaluateResultExceptionSchema = z.lazy(() => + export const ChannelSchema = z.lazy(() => z.string()); +} +export namespace Script { + export const EvaluateResultSuccessSchema = z.lazy(() => z.object({ - type: z.literal('exception'), - exceptionDetails: Script.ExceptionDetailsSchema, + type: z.literal('success'), + result: Script.RemoteValueSchema, realm: Script.RealmSchema, }), ); @@ -2100,12 +2068,51 @@ export namespace Script { }), ); } +export namespace Script { + export const ChannelValueSchema = z.lazy(() => + z.object({ + type: z.literal('channel'), + value: Script.ChannelPropertiesSchema, + }), + ); +} +export namespace Script { + export const ChannelPropertiesSchema = z.lazy(() => + z.object({ + channel: Script.ChannelSchema, + serializationOptions: Script.SerializationOptionsSchema.optional(), + ownership: Script.ResultOwnershipSchema.optional(), + }), + ); +} +export namespace Script { + export const EvaluateResultSchema = z.lazy(() => + z.union([ + Script.EvaluateResultSuccessSchema, + Script.EvaluateResultExceptionSchema, + ]), + ); +} +export namespace Script { + export const EvaluateResultExceptionSchema = z.lazy(() => + z.object({ + type: z.literal('exception'), + exceptionDetails: Script.ExceptionDetailsSchema, + realm: Script.RealmSchema, + }), + ); +} export namespace Script { export const HandleSchema = z.lazy(() => z.string()); } export namespace Script { export const InternalIdSchema = z.lazy(() => z.string()); } +export namespace Script { + export const ListLocalValueSchema = z.lazy(() => + z.array(Script.LocalValueSchema), + ); +} export namespace Script { export const LocalValueSchema = z.lazy(() => z.union([ @@ -2121,11 +2128,6 @@ export namespace Script { ]), ); } -export namespace Script { - export const ListLocalValueSchema = z.lazy(() => - z.array(Script.LocalValueSchema), - ); -} export namespace Script { export const ArrayLocalValueSchema = z.lazy(() => z.object({ @@ -2373,28 +2375,18 @@ export namespace Script { ); } export namespace Script { - export const RemoteReferenceSchema = z.lazy(() => - z.union([Script.SharedReferenceSchema, Script.RemoteObjectReferenceSchema]), - ); -} -export namespace Script { - export const SharedReferenceSchema = z.lazy(() => - z - .object({ - sharedId: Script.SharedIdSchema, - handle: Script.HandleSchema.optional(), - }) - .and(ExtensibleSchema), + export const ListRemoteValueSchema = z.lazy(() => + z.array(Script.RemoteValueSchema), ); } export namespace Script { - export const RemoteObjectReferenceSchema = z.lazy(() => - z - .object({ - handle: Script.HandleSchema, - sharedId: Script.SharedIdSchema.optional(), - }) - .and(ExtensibleSchema), + export const MappingRemoteValueSchema = z.lazy(() => + z.array( + z.tuple([ + z.union([Script.RemoteValueSchema, z.string()]), + Script.RemoteValueSchema, + ]), + ), ); } export namespace Script { @@ -2425,18 +2417,28 @@ export namespace Script { ); } export namespace Script { - export const ListRemoteValueSchema = z.lazy(() => - z.array(Script.RemoteValueSchema), + export const RemoteReferenceSchema = z.lazy(() => + z.union([Script.SharedReferenceSchema, Script.RemoteObjectReferenceSchema]), ); } export namespace Script { - export const MappingRemoteValueSchema = z.lazy(() => - z.array( - z.tuple([ - z.union([Script.RemoteValueSchema, z.string()]), - Script.RemoteValueSchema, - ]), - ), + export const SharedReferenceSchema = z.lazy(() => + z + .object({ + sharedId: Script.SharedIdSchema, + handle: Script.HandleSchema.optional(), + }) + .and(ExtensibleSchema), + ); +} +export namespace Script { + export const RemoteObjectReferenceSchema = z.lazy(() => + z + .object({ + handle: Script.HandleSchema, + sharedId: Script.SharedIdSchema.optional(), + }) + .and(ExtensibleSchema), ); } export namespace Script { @@ -2763,14 +2765,6 @@ export namespace Script { }), ); } -export namespace Script { - export const CallFunctionSchema = z.lazy(() => - z.object({ - method: z.literal('script.callFunction'), - params: Script.CallFunctionParametersSchema, - }), - ); -} export namespace Script { export const CallFunctionParametersSchema = z.lazy(() => z.object({ @@ -2785,6 +2779,14 @@ export namespace Script { }), ); } +export namespace Script { + export const CallFunctionSchema = z.lazy(() => + z.object({ + method: z.literal('script.callFunction'), + params: Script.CallFunctionParametersSchema, + }), + ); +} export namespace Script { export const EvaluateSchema = z.lazy(() => z.object({ @@ -2843,14 +2845,6 @@ export namespace Script { }), ); } -export namespace Script { - export const MessageSchema = z.lazy(() => - z.object({ - method: z.literal('script.message'), - params: Script.MessageParametersSchema, - }), - ); -} export namespace Script { export const MessageParametersSchema = z.lazy(() => z.object({ @@ -2868,6 +2862,14 @@ export namespace Script { }), ); } +export namespace Script { + export const MessageSchema = z.lazy(() => + z.object({ + method: z.literal('script.message'), + params: Script.MessageParametersSchema, + }), + ); +} export namespace Script { export const RealmDestroyedSchema = z.lazy(() => z.object({ @@ -3116,14 +3118,6 @@ export namespace Input { }), ); } -export namespace Input { - export const PerformActionsSchema = z.lazy(() => - z.object({ - method: z.literal('input.performActions'), - params: Input.PerformActionsParametersSchema, - }), - ); -} export namespace Input { export const PerformActionsParametersSchema = z.lazy(() => z.object({ @@ -3132,16 +3126,6 @@ export namespace Input { }), ); } -export namespace Input { - export const SourceActionsSchema = z.lazy(() => - z.union([ - Input.NoneSourceActionsSchema, - Input.KeySourceActionsSchema, - Input.PointerSourceActionsSchema, - Input.WheelSourceActionsSchema, - ]), - ); -} export namespace Input { export const NoneSourceActionsSchema = z.lazy(() => z.object({ @@ -3151,9 +3135,6 @@ export namespace Input { }), ); } -export namespace Input { - export const NoneSourceActionSchema = z.lazy(() => Input.PauseActionSchema); -} export namespace Input { export const KeySourceActionsSchema = z.lazy(() => z.object({ @@ -3163,15 +3144,6 @@ export namespace Input { }), ); } -export namespace Input { - export const KeySourceActionSchema = z.lazy(() => - z.union([ - Input.PauseActionSchema, - Input.KeyDownActionSchema, - Input.KeyUpActionSchema, - ]), - ); -} export namespace Input { export const PointerSourceActionsSchema = z.lazy(() => z.object({ @@ -3182,6 +3154,36 @@ export namespace Input { }), ); } +export namespace Input { + export const PerformActionsSchema = z.lazy(() => + z.object({ + method: z.literal('input.performActions'), + params: Input.PerformActionsParametersSchema, + }), + ); +} +export namespace Input { + export const SourceActionsSchema = z.lazy(() => + z.union([ + Input.NoneSourceActionsSchema, + Input.KeySourceActionsSchema, + Input.PointerSourceActionsSchema, + Input.WheelSourceActionsSchema, + ]), + ); +} +export namespace Input { + export const NoneSourceActionSchema = z.lazy(() => Input.PauseActionSchema); +} +export namespace Input { + export const KeySourceActionSchema = z.lazy(() => + z.union([ + Input.PauseActionSchema, + Input.KeyDownActionSchema, + Input.KeyUpActionSchema, + ]), + ); +} export namespace Input { export const PointerTypeSchema = z.lazy(() => z.enum(['mouse', 'pen', 'touch']), @@ -3194,6 +3196,15 @@ export namespace Input { }), ); } +export namespace Input { + export const WheelSourceActionsSchema = z.lazy(() => + z.object({ + type: z.literal('wheel'), + id: z.string(), + actions: z.array(Input.WheelSourceActionSchema), + }), + ); +} export namespace Input { export const PointerSourceActionSchema = z.lazy(() => z.union([ @@ -3204,15 +3215,6 @@ export namespace Input { ]), ); } -export namespace Input { - export const WheelSourceActionsSchema = z.lazy(() => - z.object({ - type: z.literal('wheel'), - id: z.string(), - actions: z.array(Input.WheelSourceActionSchema), - }), - ); -} export namespace Input { export const WheelSourceActionSchema = z.lazy(() => z.union([Input.PauseActionSchema, Input.WheelScrollActionSchema]), @@ -3357,6 +3359,54 @@ export namespace Input { }), ); } +export const AutofillCommandSchema = z.lazy(() => Autofill.TriggerSchema); +export namespace Autofill { + export const TriggerSchema = z.lazy(() => + z.object({ + method: z.literal('autofill.trigger'), + params: Autofill.TriggerParametersSchema, + }), + ); +} +export namespace Autofill { + export const TriggerParametersSchema = z.lazy(() => + z.object({ + context: BrowsingContext.BrowsingContextSchema, + element: Script.SharedReferenceSchema, + card: Autofill.CardSchema.optional(), + address: Autofill.AddressSchema.optional(), + }), + ); +} +export namespace Autofill { + export const FieldSchema = z.lazy(() => + z.object({ + name: Autofill.FieldNameSchema, + value: z.string(), + }), + ); +} +export namespace Autofill { + export const CardSchema = z.lazy(() => + z.object({ + number: z.string(), + name: z.string(), + expiryMonth: z.string(), + expiryYear: z.string(), + cvc: z.string(), + }), + ); +} +export namespace Autofill { + export const AddressSchema = z.lazy(() => + z.object({ + fields: z.array(Autofill.FieldSchema), + }), + ); +} +export namespace Autofill { + export const FieldNameSchema = z.lazy(() => z.string()); +} export namespace Input { export const FileDialogOpenedSchema = z.lazy(() => z.object({ @@ -3384,17 +3434,17 @@ export namespace WebExtension { export const ExtensionSchema = z.lazy(() => z.string()); } export namespace WebExtension { - export const InstallSchema = z.lazy(() => + export const InstallParametersSchema = z.lazy(() => z.object({ - method: z.literal('webExtension.install'), - params: WebExtension.InstallParametersSchema, + extensionData: WebExtension.ExtensionDataSchema, }), ); } export namespace WebExtension { - export const InstallParametersSchema = z.lazy(() => + export const InstallSchema = z.lazy(() => z.object({ - extensionData: WebExtension.ExtensionDataSchema, + method: z.literal('webExtension.install'), + params: WebExtension.InstallParametersSchema, }), ); } diff --git a/src/protocol-parser/protocol-parser.ts b/src/protocol-parser/protocol-parser.ts index 1e306b05c5..833063c1db 100644 --- a/src/protocol-parser/protocol-parser.ts +++ b/src/protocol-parser/protocol-parser.ts @@ -636,3 +636,17 @@ export namespace WebModule { } // keep-sorted end } + +export namespace Autofill { + // keep-sorted start block=yes + + export function parseTriggerParameters( + params: unknown, + ): Protocol.Autofill.TriggerParameters { + return parseObject( + params, + WebDriverBidi.Autofill.TriggerParametersSchema, + ) as Protocol.Autofill.TriggerParameters; + } + // keep-sorted end +} diff --git a/src/protocol/ErrorResponse.spec.ts b/src/protocol/ErrorResponse.spec.ts index b8f1816ed1..739060ba4f 100644 --- a/src/protocol/ErrorResponse.spec.ts +++ b/src/protocol/ErrorResponse.spec.ts @@ -25,6 +25,7 @@ describe('Exception', () => { } = { // keep-sorted start [ErrorCode.InvalidArgument]: undefined, + [ErrorCode.InvalidElementState]: undefined, [ErrorCode.InvalidSelector]: undefined, [ErrorCode.InvalidSessionId]: undefined, [ErrorCode.InvalidWebExtension]: undefined, diff --git a/src/protocol/generated/webdriver-bidi.ts b/src/protocol/generated/webdriver-bidi.ts index f5c551f985..ca140b647a 100644 --- a/src/protocol/generated/webdriver-bidi.ts +++ b/src/protocol/generated/webdriver-bidi.ts @@ -16,15 +16,30 @@ */ /** - * THIS FILE IS AUTOGENERATED by cddlconv 0.1.7. + * THIS FILE IS AUTOGENERATED by cddlconv 0.1.6. * Run `node tools/generate-bidi-types.mjs` to regenerate. * @see https://github.com/w3c/webdriver-bidi/blob/master/index.bs */ +export type Event = { + type: 'event'; +} & EventData & + Extensible; export type Command = { id: JsUint; } & CommandData & Extensible; +export type CommandResponse = { + type: 'success'; + id: JsUint; + result: ResultData; +} & Extensible; +export type EventData = + | BrowsingContextEvent + | InputEvent + | LogEvent + | NetworkEvent + | ScriptEvent; export type CommandData = | BrowserCommand | BrowsingContextCommand @@ -34,14 +49,18 @@ export type CommandData = | ScriptCommand | SessionCommand | StorageCommand - | WebExtensionCommand; + | WebExtensionCommand + | AutofillCommand; +export type ResultData = + | BrowsingContextResult + | EmptyResult + | NetworkResult + | ScriptResult + | SessionResult + | StorageResult + | WebExtensionResult; export type EmptyParams = Extensible; export type Message = CommandResponse | ErrorResponse | Event; -export type CommandResponse = { - type: 'success'; - id: JsUint; - result: ResultData; -} & Extensible; export type ErrorResponse = { type: 'error'; id: JsUint | null; @@ -49,25 +68,7 @@ export type ErrorResponse = { message: string; stacktrace?: string; } & Extensible; -export type ResultData = - | BrowsingContextResult - | EmptyResult - | NetworkResult - | ScriptResult - | SessionResult - | StorageResult - | WebExtensionResult; export type EmptyResult = Extensible; -export type Event = { - type: 'event'; -} & EventData & - Extensible; -export type EventData = - | BrowsingContextEvent - | InputEvent - | LogEvent - | NetworkEvent - | ScriptEvent; export type Extensible = { [key: string]: any; }; @@ -84,6 +85,7 @@ export type JsUint = number; export const enum ErrorCode { InvalidArgument = 'invalid argument', InvalidSelector = 'invalid selector', + InvalidElementState = 'invalid element state', InvalidSessionId = 'invalid session id', InvalidWebExtension = 'invalid web extension', MoveTargetOutOfBounds = 'move target out of bounds', @@ -118,6 +120,14 @@ export type SessionCommand = | Session.Status | Session.Subscribe | Session.Unsubscribe; +export namespace Session { + export type ProxyConfiguration = + | Session.AutodetectProxyConfiguration + | Session.DirectProxyConfiguration + | Session.ManualProxyConfiguration + | Session.PacProxyConfiguration + | Session.SystemProxyConfiguration; +} export type SessionResult = | Session.NewResult | Session.StatusResult @@ -138,14 +148,6 @@ export namespace Session { unhandledPromptBehavior?: Session.UserPromptHandler; } & Extensible; } -export namespace Session { - export type ProxyConfiguration = - | Session.AutodetectProxyConfiguration - | Session.DirectProxyConfiguration - | Session.ManualProxyConfiguration - | Session.PacProxyConfiguration - | Session.SystemProxyConfiguration; -} export namespace Session { export type AutodetectProxyConfiguration = { proxyType: 'autodetect'; @@ -421,14 +423,6 @@ export type BrowsingContextCommand = | BrowsingContext.Reload | BrowsingContext.SetViewport | BrowsingContext.TraverseHistory; -export type BrowsingContextResult = - | BrowsingContext.CaptureScreenshotResult - | BrowsingContext.CreateResult - | BrowsingContext.GetTreeResult - | BrowsingContext.LocateNodesResult - | BrowsingContext.NavigateResult - | BrowsingContext.PrintResult - | BrowsingContext.TraverseHistoryResult; export type BrowsingContextEvent = | BrowsingContext.ContextCreated | BrowsingContext.ContextDestroyed @@ -444,6 +438,14 @@ export type BrowsingContextEvent = | BrowsingContext.NavigationStarted | BrowsingContext.UserPromptClosed | BrowsingContext.UserPromptOpened; +export type BrowsingContextResult = + | BrowsingContext.CaptureScreenshotResult + | BrowsingContext.CreateResult + | BrowsingContext.GetTreeResult + | BrowsingContext.LocateNodesResult + | BrowsingContext.NavigateResult + | BrowsingContext.PrintResult + | BrowsingContext.TraverseHistoryResult; export namespace BrowsingContext { export type BrowsingContext = string; } @@ -547,12 +549,6 @@ export namespace BrowsingContext { context: BrowsingContext.BrowsingContext; }; } -export namespace BrowsingContext { - export type CaptureScreenshot = { - method: 'browsingContext.captureScreenshot'; - params: BrowsingContext.CaptureScreenshotParameters; - }; -} export namespace BrowsingContext { export type CaptureScreenshotParameters = { context: BrowsingContext.BrowsingContext; @@ -564,6 +560,12 @@ export namespace BrowsingContext { clip?: BrowsingContext.ClipRectangle; }; } +export namespace BrowsingContext { + export type CaptureScreenshot = { + method: 'browsingContext.captureScreenshot'; + params: BrowsingContext.CaptureScreenshotParameters; + }; +} export namespace BrowsingContext { export type ImageFormat = { type: string; @@ -671,12 +673,6 @@ export namespace BrowsingContext { userText?: string; }; } -export namespace BrowsingContext { - export type LocateNodes = { - method: 'browsingContext.locateNodes'; - params: BrowsingContext.LocateNodesParameters; - }; -} export namespace BrowsingContext { export type LocateNodesParameters = { context: BrowsingContext.BrowsingContext; @@ -689,6 +685,12 @@ export namespace BrowsingContext { startNodes?: [Script.SharedReference, ...Script.SharedReference[]]; }; } +export namespace BrowsingContext { + export type LocateNodes = { + method: 'browsingContext.locateNodes'; + params: BrowsingContext.LocateNodesParameters; + }; +} export namespace BrowsingContext { export type LocateNodesResult = { nodes: [...Script.NodeRemoteValue[]]; @@ -1167,13 +1169,13 @@ export type NetworkCommand = | Network.RemoveIntercept | Network.SetCacheBehavior | Network.SetExtraHeaders; -export type NetworkResult = Network.AddInterceptResult; export type NetworkEvent = | Network.AuthRequired | Network.BeforeRequestSent | Network.FetchError | Network.ResponseCompleted | Network.ResponseStarted; +export type NetworkResult = Network.AddInterceptResult; export namespace Network { export type AuthChallenge = { scheme: string; @@ -1384,12 +1386,6 @@ export namespace Network { collector: Network.Collector; }; } -export namespace Network { - export type AddIntercept = { - method: 'network.addIntercept'; - params: Network.AddInterceptParameters; - }; -} export namespace Network { export type AddInterceptParameters = { phases: [Network.InterceptPhase, ...Network.InterceptPhase[]]; @@ -1400,6 +1396,12 @@ export namespace Network { urlPatterns?: [...Network.UrlPattern[]]; }; } +export namespace Network { + export type AddIntercept = { + method: 'network.addIntercept'; + params: Network.AddInterceptParameters; + }; +} export namespace Network { export const enum InterceptPhase { BeforeRequestSent = 'beforeRequestSent', @@ -1584,56 +1586,30 @@ export namespace Network { userContexts?: [Browser.UserContext, ...Browser.UserContext[]]; }; } -export namespace Network { - export type AuthRequired = { - method: 'network.authRequired'; - params: Network.AuthRequiredParameters; - }; -} +export type ScriptEvent = + | Script.Message + | Script.RealmCreated + | Script.RealmDestroyed; export namespace Network { export type AuthRequiredParameters = Network.BaseParameters & { response: Network.ResponseData; }; } -export namespace Network { - export type BeforeRequestSent = { - method: 'network.beforeRequestSent'; - params: Network.BeforeRequestSentParameters; - }; -} export namespace Network { export type BeforeRequestSentParameters = Network.BaseParameters & { initiator?: Network.Initiator; }; } -export namespace Network { - export type FetchError = { - method: 'network.fetchError'; - params: Network.FetchErrorParameters; - }; -} export namespace Network { export type FetchErrorParameters = Network.BaseParameters & { errorText: string; }; } -export namespace Network { - export type ResponseCompleted = { - method: 'network.responseCompleted'; - params: Network.ResponseCompletedParameters; - }; -} export namespace Network { export type ResponseCompletedParameters = Network.BaseParameters & { response: Network.ResponseData; }; } -export namespace Network { - export type ResponseStarted = { - method: 'network.responseStarted'; - params: Network.ResponseStartedParameters; - }; -} export namespace Network { export type ResponseStartedParameters = Network.BaseParameters & { response: Network.ResponseData; @@ -1650,13 +1626,55 @@ export type ScriptResult = | Script.AddPreloadScriptResult | Script.EvaluateResult | Script.GetRealmsResult; -export type ScriptEvent = - | Script.Message - | Script.RealmCreated - | Script.RealmDestroyed; +export namespace Network { + export type AuthRequired = { + method: 'network.authRequired'; + params: Network.AuthRequiredParameters; + }; +} +export namespace Network { + export type BeforeRequestSent = { + method: 'network.beforeRequestSent'; + params: Network.BeforeRequestSentParameters; + }; +} +export namespace Network { + export type FetchError = { + method: 'network.fetchError'; + params: Network.FetchErrorParameters; + }; +} +export namespace Network { + export type ResponseCompleted = { + method: 'network.responseCompleted'; + params: Network.ResponseCompletedParameters; + }; +} +export namespace Network { + export type ResponseStarted = { + method: 'network.responseStarted'; + params: Network.ResponseStartedParameters; + }; +} export namespace Script { export type Channel = string; } +export namespace Script { + export type EvaluateResultSuccess = { + type: 'success'; + result: Script.RemoteValue; + realm: Script.Realm; + }; +} +export namespace Script { + export type ExceptionDetails = { + columnNumber: JsUint; + exception: Script.RemoteValue; + lineNumber: JsUint; + stackTrace: Script.StackTrace; + text: string; + }; +} export namespace Script { export type ChannelValue = { type: 'channel'; @@ -1675,13 +1693,6 @@ export namespace Script { | Script.EvaluateResultSuccess | Script.EvaluateResultException; } -export namespace Script { - export type EvaluateResultSuccess = { - type: 'success'; - result: Script.RemoteValue; - realm: Script.Realm; - }; -} export namespace Script { export type EvaluateResultException = { type: 'exception'; @@ -1689,21 +1700,15 @@ export namespace Script { realm: Script.Realm; }; } -export namespace Script { - export type ExceptionDetails = { - columnNumber: JsUint; - exception: Script.RemoteValue; - lineNumber: JsUint; - stackTrace: Script.StackTrace; - text: string; - }; -} export namespace Script { export type Handle = string; } export namespace Script { export type InternalId = string; } +export namespace Script { + export type ListLocalValue = [...Script.LocalValue[]]; +} export namespace Script { export type LocalValue = | Script.RemoteReference @@ -1716,9 +1721,6 @@ export namespace Script { | Script.RegExpLocalValue | Script.SetLocalValue; } -export namespace Script { - export type ListLocalValue = [...Script.LocalValue[]]; -} export namespace Script { export type ArrayLocalValue = { type: 'array'; @@ -1890,21 +1892,12 @@ export namespace Script { | 'worklet'; } export namespace Script { - export type RemoteReference = - | Script.SharedReference - | Script.RemoteObjectReference; -} -export namespace Script { - export type SharedReference = { - sharedId: Script.SharedId; - handle?: Script.Handle; - } & Extensible; + export type ListRemoteValue = [...Script.RemoteValue[]]; } export namespace Script { - export type RemoteObjectReference = { - handle: Script.Handle; - sharedId?: Script.SharedId; - } & Extensible; + export type MappingRemoteValue = [ + ...[Script.RemoteValue | string, Script.RemoteValue][], + ]; } export namespace Script { export type RemoteValue = @@ -1931,12 +1924,21 @@ export namespace Script { | Script.WindowProxyRemoteValue; } export namespace Script { - export type ListRemoteValue = [...Script.RemoteValue[]]; + export type RemoteReference = + | Script.SharedReference + | Script.RemoteObjectReference; } export namespace Script { - export type MappingRemoteValue = [ - ...[Script.RemoteValue | string, Script.RemoteValue][], - ]; + export type SharedReference = { + sharedId: Script.SharedId; + handle?: Script.Handle; + } & Extensible; +} +export namespace Script { + export type RemoteObjectReference = { + handle: Script.Handle; + sharedId?: Script.SharedId; + } & Extensible; } export namespace Script { export type SymbolRemoteValue = { @@ -2198,12 +2200,6 @@ export namespace Script { target: Script.Target; }; } -export namespace Script { - export type CallFunction = { - method: 'script.callFunction'; - params: Script.CallFunctionParameters; - }; -} export namespace Script { export type CallFunctionParameters = { functionDeclaration: string; @@ -2219,6 +2215,12 @@ export namespace Script { userActivation?: boolean; }; } +export namespace Script { + export type CallFunction = { + method: 'script.callFunction'; + params: Script.CallFunctionParameters; + }; +} export namespace Script { export type Evaluate = { method: 'script.evaluate'; @@ -2266,12 +2268,6 @@ export namespace Script { script: Script.PreloadScript; }; } -export namespace Script { - export type Message = { - method: 'script.message'; - params: Script.MessageParameters; - }; -} export namespace Script { export type MessageParameters = { channel: Script.Channel; @@ -2285,6 +2281,12 @@ export namespace Script { params: Script.RealmInfo; }; } +export namespace Script { + export type Message = { + method: 'script.message'; + params: Script.MessageParameters; + }; +} export namespace Script { export type RealmDestroyed = { method: 'script.realmDestroyed'; @@ -2463,25 +2465,12 @@ export namespace Input { element: Script.SharedReference; }; } -export namespace Input { - export type PerformActions = { - method: 'input.performActions'; - params: Input.PerformActionsParameters; - }; -} export namespace Input { export type PerformActionsParameters = { context: BrowsingContext.BrowsingContext; actions: [...Input.SourceActions[]]; }; } -export namespace Input { - export type SourceActions = - | Input.NoneSourceActions - | Input.KeySourceActions - | Input.PointerSourceActions - | Input.WheelSourceActions; -} export namespace Input { export type NoneSourceActions = { type: 'none'; @@ -2489,9 +2478,6 @@ export namespace Input { actions: [...Input.NoneSourceAction[]]; }; } -export namespace Input { - export type NoneSourceAction = Input.PauseAction; -} export namespace Input { export type KeySourceActions = { type: 'key'; @@ -2499,12 +2485,6 @@ export namespace Input { actions: [...Input.KeySourceAction[]]; }; } -export namespace Input { - export type KeySourceAction = - | Input.PauseAction - | Input.KeyDownAction - | Input.KeyUpAction; -} export namespace Input { export type PointerSourceActions = { type: 'pointer'; @@ -2513,6 +2493,28 @@ export namespace Input { actions: [...Input.PointerSourceAction[]]; }; } +export namespace Input { + export type PerformActions = { + method: 'input.performActions'; + params: Input.PerformActionsParameters; + }; +} +export namespace Input { + export type SourceActions = + | Input.NoneSourceActions + | Input.KeySourceActions + | Input.PointerSourceActions + | Input.WheelSourceActions; +} +export namespace Input { + export type NoneSourceAction = Input.PauseAction; +} +export namespace Input { + export type KeySourceAction = + | Input.PauseAction + | Input.KeyDownAction + | Input.KeyUpAction; +} export namespace Input { export const enum PointerType { Mouse = 'mouse', @@ -2528,13 +2530,6 @@ export namespace Input { pointerType?: Input.PointerType; }; } -export namespace Input { - export type PointerSourceAction = - | Input.PauseAction - | Input.PointerDownAction - | Input.PointerUpAction - | Input.PointerMoveAction; -} export namespace Input { export type WheelSourceActions = { type: 'wheel'; @@ -2542,6 +2537,13 @@ export namespace Input { actions: [...Input.WheelSourceAction[]]; }; } +export namespace Input { + export type PointerSourceAction = + | Input.PauseAction + | Input.PointerDownAction + | Input.PointerUpAction + | Input.PointerMoveAction; +} export namespace Input { export type WheelSourceAction = Input.PauseAction | Input.WheelScrollAction; } @@ -2663,6 +2665,44 @@ export namespace Input { files: [...string[]]; }; } +export type AutofillCommand = Autofill.Trigger; +export namespace Autofill { + export type Trigger = { + method: 'autofill.trigger'; + params: Autofill.TriggerParameters; + }; +} +export namespace Autofill { + export type TriggerParameters = { + context: BrowsingContext.BrowsingContext; + element: Script.SharedReference; + card?: Autofill.Card; + address?: Autofill.Address; + }; +} +export namespace Autofill { + export type Field = { + name: Autofill.FieldName; + value: string; + }; +} +export namespace Autofill { + export type Card = { + number: string; + name: string; + expiryMonth: string; + expiryYear: string; + cvc: string; + }; +} +export namespace Autofill { + export type Address = { + fields: [...Autofill.Field[]]; + }; +} +export namespace Autofill { + export type FieldName = string; +} export namespace Input { export type FileDialogOpened = { method: 'input.fileDialogOpened'; @@ -2682,14 +2722,14 @@ export namespace WebExtension { export type Extension = string; } export namespace WebExtension { - export type Install = { - method: 'webExtension.install'; - params: WebExtension.InstallParameters; + export type InstallParameters = { + extensionData: WebExtension.ExtensionData; }; } export namespace WebExtension { - export type InstallParameters = { - extensionData: WebExtension.ExtensionData; + export type Install = { + method: 'webExtension.install'; + params: WebExtension.InstallParameters; }; } export namespace WebExtension { diff --git a/tests/autofill/__init__.py b/tests/autofill/__init__.py new file mode 100644 index 0000000000..7370cf3cd2 --- /dev/null +++ b/tests/autofill/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2025 Google LLC. +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/autofill/test_autofill_trigger.py b/tests/autofill/test_autofill_trigger.py new file mode 100644 index 0000000000..d6d4267a59 --- /dev/null +++ b/tests/autofill/test_autofill_trigger.py @@ -0,0 +1,384 @@ +# Copyright 2025 Google LLC. +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from test_helpers import execute_command, goto_url + + +async def verify_field_value(websocket, context_id, field_id, expected_value): + """Helper function to verify that a form field has the expected value.""" + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': f'document.getElementById("{field_id}").value', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + assert resp['result']['value'] == expected_value, f"Field '{field_id}' expected '{expected_value}' but got '{resp['result']['value']}'" + + +@pytest.mark.asyncio +async def test_autofill_trigger_with_card(websocket, context_id, html): + """Test autofill.trigger command with credit card data.""" + # Create a simple form with credit card fields + await goto_url( + websocket, context_id, + html(''' +
+ + + + + +
+ ''') + ) + + # Get a reference to the card number input field + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': 'document.getElementById("cardNumber")', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + + element_shared_id = resp['result']['sharedId'] + + # Execute autofill.trigger with card data + card_data = { + 'number': '4111111111111111', + 'name': 'John Doe', + 'expiryMonth': '12', + 'expiryYear': '2025', + 'cvc': '123' + } + + resp = await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': element_shared_id + }, + 'card': card_data + } + }) + + # The command should return an empty result + assert resp == {} + + # Verify that the form fields were actually filled with the card data + await verify_field_value(websocket, context_id, "cardNumber", "4111111111111111") + await verify_field_value(websocket, context_id, "cardName", "John Doe") + await verify_field_value(websocket, context_id, "expiryMonth", "12") + await verify_field_value(websocket, context_id, "expiryYear", "2025") + await verify_field_value(websocket, context_id, "cvc", "123") + + +@pytest.mark.asyncio +async def test_autofill_trigger_with_address(websocket, context_id, html): + """Test autofill.trigger command with address data.""" + # Create a simple form with address fields + await goto_url( + websocket, context_id, + html(''' +
+ + + + + + +
+ ''') + ) + + # Get a reference to the first name input field + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': 'document.getElementById("firstName")', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + + element_shared_id = resp['result']['sharedId'] + + # Execute autofill.trigger with address data + address_data = { + 'fields': [ + {'name': 'NAME_FIRST', 'value': 'Jane'}, + {'name': 'NAME_LAST', 'value': 'Smith'}, + {'name': 'ADDRESS_HOME_LINE1', 'value': '123 Main St'}, + {'name': 'ADDRESS_HOME_CITY', 'value': 'Anytown'}, + {'name': 'ADDRESS_HOME_STATE', 'value': 'CA'}, + {'name': 'ADDRESS_HOME_ZIP', 'value': '12345'} + ] + } + + resp = await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': element_shared_id + }, + 'address': address_data + } + }) + + # The command should return an empty result + assert resp == {} + + # Verify that the address form fields were actually filled + await verify_field_value(websocket, context_id, "firstName", "Jane") + await verify_field_value(websocket, context_id, "lastName", "Smith") + await verify_field_value(websocket, context_id, "street", "123 Main St") + await verify_field_value(websocket, context_id, "city", "Anytown") + await verify_field_value(websocket, context_id, "state", "CA") + await verify_field_value(websocket, context_id, "zipCode", "12345") + + +@pytest.mark.asyncio +async def test_autofill_trigger_with_both_card_and_address(websocket, context_id, html): + """Test autofill.trigger command with both card and address data.""" + # Create a comprehensive form + await goto_url( + websocket, context_id, + html(''' +
+ + + + + + + + + + + + + + +
+ ''') + ) + + # Get a reference to the card number input field + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': 'document.getElementById("cardNumber")', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + + element_shared_id = resp['result']['sharedId'] + + # Execute autofill.trigger with both card and address data + card_data = { + 'number': '4111111111111111', + 'name': 'John Doe', + 'expiryMonth': '12', + 'expiryYear': '2025', + 'cvc': '123' + } + + address_data = { + 'fields': [ + {'name': 'firstName', 'value': 'John'}, + {'name': 'lastName', 'value': 'Doe'}, + {'name': 'street', 'value': '456 Oak Ave'}, + {'name': 'city', 'value': 'Springfield'}, + {'name': 'state', 'value': 'IL'}, + {'name': 'zipCode', 'value': '62701'} + ] + } + + # The command should fail with an error about unsupported field type + with pytest.raises(Exception) as exc_info: + await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': element_shared_id + }, + 'card': card_data, + 'address': address_data + } + }) + + # Verify that the error is about unsupported field type + error = exc_info.value.args[0] + assert error['error'] == 'unknown error' + assert 'Card and address cannot both be provided' in error['message'] + +@pytest.mark.asyncio +async def test_autofill_trigger_no_card_or_address(websocket, context_id, html): + """Test autofill.trigger command with minimal parameters (no card or address data).""" + # Create a simple input field + await goto_url( + websocket, context_id, + html('') + ) + + # Get a reference to the input field + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': 'document.getElementById("testField")', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + + element_shared_id = resp['result']['sharedId'] + + with pytest.raises(Exception) as exc_info: + await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': element_shared_id + }, + } + }) + + # Verify that the error is about unsupported field type + error = exc_info.value.args[0] + assert error['error'] == 'unknown error' + assert 'Either card or address must be provided' in error['message'] + + +@pytest.mark.asyncio +async def test_autofill_trigger_invalid_element(websocket, context_id, html): + """Test autofill.trigger command with invalid element reference.""" + # Create a simple page + await goto_url(websocket, context_id, html('
Test page
')) + + # Try to execute autofill.trigger with an invalid shared ID + with pytest.raises(Exception) as exc_info: + await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': 'invalid-shared-id' + }, + 'card': { + 'number': '4111111111111111', + 'name': 'Test User', + 'expiryMonth': '12', + 'expiryYear': '2025', + 'cvc': '123' + } + } + }) + error = exc_info.value.args[0] + assert error['error'] == 'no such node' + assert 'SharedId "invalid-shared-id" was not found' in error['message'] + + +@pytest.mark.asyncio +async def test_autofill_trigger_unknown_field_type_error(websocket, context_id, html): + """Test that autofill.trigger command fails with unknown field types.""" + # Create a form with various field types + await goto_url( + websocket, context_id, + html(''' +
+ + + + + +
+ ''') + ) + + # Test with email field + resp = await execute_command( + websocket, { + 'method': 'script.evaluate', + 'params': { + 'expression': 'document.getElementById("email")', + 'target': { + 'context': context_id + }, + 'awaitPromise': False + } + }) + + element_shared_id = resp['result']['sharedId'] + + address_data = { + 'fields': [ + {'name': 'EMAIL_ADDRESS', 'value': 'test@example.com'}, + {'name': 'COMPANY_NAME', 'value': 'Test Company'}, + {'name': 'ADDRESS_HOME_COUNTRY', 'value': 'US'}, + {'name': 'UNKNOWN_TYPE', 'value': 'This is a test note'} + ] + } + + # The command should fail with an error about unsupported field type + with pytest.raises(Exception) as exc_info: + await execute_command( + websocket, { + 'method': 'autofill.trigger', + 'params': { + 'context': context_id, + 'element': { + 'sharedId': element_shared_id + }, + 'address': address_data + } + }) + + # Verify that the error is about unsupported field type + error = exc_info.value.args[0] + assert error['error'] == 'unknown error' + assert 'Unsupported field type' in error['message']