expect-sdk 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +48 -0
- package/.expect/replays/08a6cacb-cdfb-47ba-9cf7-41a13ac07a36.html +286 -0
- package/.expect/replays/08a6cacb-cdfb-47ba-9cf7-41a13ac07a36.ndjson +2 -0
- package/.expect/replays/08a6cacb-cdfb-47ba-9cf7-41a13ac07a36.ndjson.js +2 -0
- package/.expect/replays/0abc2d0c-30d4-405b-8f6a-ad55eab10797.html +286 -0
- package/.expect/replays/0abc2d0c-30d4-405b-8f6a-ad55eab10797.ndjson +2 -0
- package/.expect/replays/0abc2d0c-30d4-405b-8f6a-ad55eab10797.ndjson.js +2 -0
- package/.expect/replays/0be009ad-fc3d-4aa8-81e2-2473dddf876a.html +286 -0
- package/.expect/replays/0be009ad-fc3d-4aa8-81e2-2473dddf876a.ndjson +7 -0
- package/.expect/replays/0be009ad-fc3d-4aa8-81e2-2473dddf876a.ndjson.js +2 -0
- package/.expect/replays/0bf0f4f1-9c7d-4dac-ae8f-6990ec08b82b.html +286 -0
- package/.expect/replays/0bf0f4f1-9c7d-4dac-ae8f-6990ec08b82b.ndjson +10 -0
- package/.expect/replays/0bf0f4f1-9c7d-4dac-ae8f-6990ec08b82b.ndjson.js +2 -0
- package/.expect/replays/0cdb0236-3fdf-4c48-8ef1-fbc8539a8d32.html +286 -0
- package/.expect/replays/0cdb0236-3fdf-4c48-8ef1-fbc8539a8d32.ndjson +49 -0
- package/.expect/replays/0cdb0236-3fdf-4c48-8ef1-fbc8539a8d32.ndjson.js +2 -0
- package/.expect/replays/0dbbf37b-6749-4973-ae20-b37b9b734ce6.html +286 -0
- package/.expect/replays/0dbbf37b-6749-4973-ae20-b37b9b734ce6.ndjson +44 -0
- package/.expect/replays/0dbbf37b-6749-4973-ae20-b37b9b734ce6.ndjson.js +2 -0
- package/.expect/replays/15009a95-16f4-4f14-9f52-a2a650b6de23.html +286 -0
- package/.expect/replays/15009a95-16f4-4f14-9f52-a2a650b6de23.ndjson +23 -0
- package/.expect/replays/15009a95-16f4-4f14-9f52-a2a650b6de23.ndjson.js +2 -0
- package/.expect/replays/2095af47-e1dc-444b-ab84-f614d755fd04.html +286 -0
- package/.expect/replays/2095af47-e1dc-444b-ab84-f614d755fd04.ndjson +10 -0
- package/.expect/replays/2095af47-e1dc-444b-ab84-f614d755fd04.ndjson.js +2 -0
- package/.expect/replays/26962ef6-a3ac-4033-aee6-d09414c2232d.html +286 -0
- package/.expect/replays/26962ef6-a3ac-4033-aee6-d09414c2232d.ndjson +8 -0
- package/.expect/replays/26962ef6-a3ac-4033-aee6-d09414c2232d.ndjson.js +2 -0
- package/.expect/replays/28d1ed69-05c0-44dc-a369-77b0d37b64c8.html +286 -0
- package/.expect/replays/28d1ed69-05c0-44dc-a369-77b0d37b64c8.ndjson +12 -0
- package/.expect/replays/28d1ed69-05c0-44dc-a369-77b0d37b64c8.ndjson.js +2 -0
- package/.expect/replays/2ece9734-85bf-4d45-9738-7e3c7a4b6c9e.html +286 -0
- package/.expect/replays/2ece9734-85bf-4d45-9738-7e3c7a4b6c9e.ndjson +20 -0
- package/.expect/replays/2ece9734-85bf-4d45-9738-7e3c7a4b6c9e.ndjson.js +2 -0
- package/.expect/replays/301ecd28-499b-4367-80c8-8f5c740a4011.html +286 -0
- package/.expect/replays/301ecd28-499b-4367-80c8-8f5c740a4011.ndjson +6 -0
- package/.expect/replays/301ecd28-499b-4367-80c8-8f5c740a4011.ndjson.js +2 -0
- package/.expect/replays/323fdb67-102e-45c2-a6ae-2ed78e590928.html +286 -0
- package/.expect/replays/323fdb67-102e-45c2-a6ae-2ed78e590928.ndjson +7 -0
- package/.expect/replays/323fdb67-102e-45c2-a6ae-2ed78e590928.ndjson.js +2 -0
- package/.expect/replays/338b9a53-a211-448a-99cd-a95873edef79.html +286 -0
- package/.expect/replays/338b9a53-a211-448a-99cd-a95873edef79.ndjson +7 -0
- package/.expect/replays/338b9a53-a211-448a-99cd-a95873edef79.ndjson.js +2 -0
- package/.expect/replays/33bfd732-9116-4200-b732-41faba42ae75.html +286 -0
- package/.expect/replays/33bfd732-9116-4200-b732-41faba42ae75.ndjson +10 -0
- package/.expect/replays/33bfd732-9116-4200-b732-41faba42ae75.ndjson.js +2 -0
- package/.expect/replays/33eb7162-e0c8-40ae-8e72-8ad273b0fca7.html +286 -0
- package/.expect/replays/33eb7162-e0c8-40ae-8e72-8ad273b0fca7.ndjson +7 -0
- package/.expect/replays/33eb7162-e0c8-40ae-8e72-8ad273b0fca7.ndjson.js +2 -0
- package/.expect/replays/365939fb-9693-4219-b5f5-0bafef524617.html +286 -0
- package/.expect/replays/365939fb-9693-4219-b5f5-0bafef524617.ndjson +2 -0
- package/.expect/replays/365939fb-9693-4219-b5f5-0bafef524617.ndjson.js +2 -0
- package/.expect/replays/383ea7a8-0ff8-4958-a148-3032f0a52eab.html +286 -0
- package/.expect/replays/383ea7a8-0ff8-4958-a148-3032f0a52eab.ndjson +54 -0
- package/.expect/replays/383ea7a8-0ff8-4958-a148-3032f0a52eab.ndjson.js +2 -0
- package/.expect/replays/397a5665-4344-441b-a424-2ac53df712a1.html +286 -0
- package/.expect/replays/397a5665-4344-441b-a424-2ac53df712a1.ndjson +14 -0
- package/.expect/replays/397a5665-4344-441b-a424-2ac53df712a1.ndjson.js +2 -0
- package/.expect/replays/39a5d9cc-72d0-483d-bfcc-506a6fc85f13.html +286 -0
- package/.expect/replays/39a5d9cc-72d0-483d-bfcc-506a6fc85f13.ndjson +10 -0
- package/.expect/replays/39a5d9cc-72d0-483d-bfcc-506a6fc85f13.ndjson.js +2 -0
- package/.expect/replays/39ccd62e-2f4c-4a4a-9b43-40524b7a945b.html +286 -0
- package/.expect/replays/39ccd62e-2f4c-4a4a-9b43-40524b7a945b.ndjson +14 -0
- package/.expect/replays/39ccd62e-2f4c-4a4a-9b43-40524b7a945b.ndjson.js +2 -0
- package/.expect/replays/3eff073f-7e14-49d8-a2e2-1b7634a117cd.html +286 -0
- package/.expect/replays/3eff073f-7e14-49d8-a2e2-1b7634a117cd.ndjson +45 -0
- package/.expect/replays/3eff073f-7e14-49d8-a2e2-1b7634a117cd.ndjson.js +2 -0
- package/.expect/replays/3f144b2f-78ce-4d23-bd96-99994bf07edd.html +286 -0
- package/.expect/replays/3f144b2f-78ce-4d23-bd96-99994bf07edd.ndjson +34 -0
- package/.expect/replays/3f144b2f-78ce-4d23-bd96-99994bf07edd.ndjson.js +2 -0
- package/.expect/replays/436e0182-8590-4520-97b5-d62b08ebe822.html +286 -0
- package/.expect/replays/436e0182-8590-4520-97b5-d62b08ebe822.ndjson +15 -0
- package/.expect/replays/436e0182-8590-4520-97b5-d62b08ebe822.ndjson.js +2 -0
- package/.expect/replays/43e9a6e6-ce7d-4ed4-b593-f07ce6d53009.html +286 -0
- package/.expect/replays/43e9a6e6-ce7d-4ed4-b593-f07ce6d53009.ndjson +85 -0
- package/.expect/replays/43e9a6e6-ce7d-4ed4-b593-f07ce6d53009.ndjson.js +2 -0
- package/.expect/replays/4568fc07-ea40-4740-be6f-0f6a8e632175.html +286 -0
- package/.expect/replays/4568fc07-ea40-4740-be6f-0f6a8e632175.ndjson +53 -0
- package/.expect/replays/4568fc07-ea40-4740-be6f-0f6a8e632175.ndjson.js +2 -0
- package/.expect/replays/47b43574-9b41-44be-af9c-fb7c0a81196f.html +286 -0
- package/.expect/replays/47b43574-9b41-44be-af9c-fb7c0a81196f.ndjson +2 -0
- package/.expect/replays/47b43574-9b41-44be-af9c-fb7c0a81196f.ndjson.js +2 -0
- package/.expect/replays/47d846d6-f86e-46e4-94d7-f0abff232b20.html +286 -0
- package/.expect/replays/47d846d6-f86e-46e4-94d7-f0abff232b20.ndjson +10 -0
- package/.expect/replays/47d846d6-f86e-46e4-94d7-f0abff232b20.ndjson.js +2 -0
- package/.expect/replays/486cd227-9d22-49cf-b050-cb546d374206.html +286 -0
- package/.expect/replays/486cd227-9d22-49cf-b050-cb546d374206.ndjson +2 -0
- package/.expect/replays/486cd227-9d22-49cf-b050-cb546d374206.ndjson.js +2 -0
- package/.expect/replays/4c53e4c2-ece4-4767-87fe-394fe0ab4300.html +286 -0
- package/.expect/replays/4c53e4c2-ece4-4767-87fe-394fe0ab4300.ndjson +33 -0
- package/.expect/replays/4c53e4c2-ece4-4767-87fe-394fe0ab4300.ndjson.js +2 -0
- package/.expect/replays/4d1c0166-77e7-49ee-9bdc-9e3382e7f60c.html +286 -0
- package/.expect/replays/4d1c0166-77e7-49ee-9bdc-9e3382e7f60c.ndjson +58 -0
- package/.expect/replays/4d1c0166-77e7-49ee-9bdc-9e3382e7f60c.ndjson.js +2 -0
- package/.expect/replays/4ee7ecf6-20ce-42c3-8ed6-9476e74498eb.html +286 -0
- package/.expect/replays/4ee7ecf6-20ce-42c3-8ed6-9476e74498eb.ndjson +10 -0
- package/.expect/replays/4ee7ecf6-20ce-42c3-8ed6-9476e74498eb.ndjson.js +2 -0
- package/.expect/replays/5438a8a6-ef42-42e2-8764-fde7c6529d95.html +286 -0
- package/.expect/replays/5438a8a6-ef42-42e2-8764-fde7c6529d95.ndjson +33 -0
- package/.expect/replays/5438a8a6-ef42-42e2-8764-fde7c6529d95.ndjson.js +2 -0
- package/.expect/replays/5709193a-1153-46b2-b19c-736e4bda525d.html +286 -0
- package/.expect/replays/5709193a-1153-46b2-b19c-736e4bda525d.ndjson +16 -0
- package/.expect/replays/5709193a-1153-46b2-b19c-736e4bda525d.ndjson.js +2 -0
- package/.expect/replays/5eee229c-5e60-4cb2-a1c2-f7720a94ea1c.html +286 -0
- package/.expect/replays/5eee229c-5e60-4cb2-a1c2-f7720a94ea1c.ndjson +2 -0
- package/.expect/replays/5eee229c-5e60-4cb2-a1c2-f7720a94ea1c.ndjson.js +2 -0
- package/.expect/replays/63657ec6-87d8-4250-a0db-05d12fa2983e.html +286 -0
- package/.expect/replays/63657ec6-87d8-4250-a0db-05d12fa2983e.ndjson +48 -0
- package/.expect/replays/63657ec6-87d8-4250-a0db-05d12fa2983e.ndjson.js +2 -0
- package/.expect/replays/6623c0d4-cfcf-461a-8029-0f157ff21080.html +286 -0
- package/.expect/replays/6623c0d4-cfcf-461a-8029-0f157ff21080.ndjson +8 -0
- package/.expect/replays/6623c0d4-cfcf-461a-8029-0f157ff21080.ndjson.js +2 -0
- package/.expect/replays/69a4dab6-06ad-4d54-99c9-1113d6f5a033.html +286 -0
- package/.expect/replays/69a4dab6-06ad-4d54-99c9-1113d6f5a033.ndjson +7 -0
- package/.expect/replays/69a4dab6-06ad-4d54-99c9-1113d6f5a033.ndjson.js +2 -0
- package/.expect/replays/6b3fae01-5e61-48e3-b675-334572bdaf67.html +286 -0
- package/.expect/replays/6b3fae01-5e61-48e3-b675-334572bdaf67.ndjson +14 -0
- package/.expect/replays/6b3fae01-5e61-48e3-b675-334572bdaf67.ndjson.js +2 -0
- package/.expect/replays/709859dd-cd9d-4f4a-93f3-0185631feaf5.html +286 -0
- package/.expect/replays/709859dd-cd9d-4f4a-93f3-0185631feaf5.ndjson +2 -0
- package/.expect/replays/709859dd-cd9d-4f4a-93f3-0185631feaf5.ndjson.js +2 -0
- package/.expect/replays/76b454d4-ba48-47a0-9336-486a7b106322.html +286 -0
- package/.expect/replays/76b454d4-ba48-47a0-9336-486a7b106322.ndjson +37 -0
- package/.expect/replays/76b454d4-ba48-47a0-9336-486a7b106322.ndjson.js +2 -0
- package/.expect/replays/76c75bfa-d266-487e-a4d2-54d6f64760b5.html +286 -0
- package/.expect/replays/76c75bfa-d266-487e-a4d2-54d6f64760b5.ndjson +18 -0
- package/.expect/replays/76c75bfa-d266-487e-a4d2-54d6f64760b5.ndjson.js +2 -0
- package/.expect/replays/78333bb7-5172-4839-98a0-745372a1032b.html +286 -0
- package/.expect/replays/78333bb7-5172-4839-98a0-745372a1032b.ndjson +65 -0
- package/.expect/replays/78333bb7-5172-4839-98a0-745372a1032b.ndjson.js +2 -0
- package/.expect/replays/7be24ce2-8544-492e-9b66-b56c0c1e027b.html +286 -0
- package/.expect/replays/7be24ce2-8544-492e-9b66-b56c0c1e027b.ndjson +10 -0
- package/.expect/replays/7be24ce2-8544-492e-9b66-b56c0c1e027b.ndjson.js +2 -0
- package/.expect/replays/825423b3-7e83-4037-b0b7-c4eafe6282b8.html +286 -0
- package/.expect/replays/825423b3-7e83-4037-b0b7-c4eafe6282b8.ndjson +54 -0
- package/.expect/replays/825423b3-7e83-4037-b0b7-c4eafe6282b8.ndjson.js +2 -0
- package/.expect/replays/83641ba6-ccfa-4400-88ee-b8e4a1775c12.html +286 -0
- package/.expect/replays/83641ba6-ccfa-4400-88ee-b8e4a1775c12.ndjson +18 -0
- package/.expect/replays/83641ba6-ccfa-4400-88ee-b8e4a1775c12.ndjson.js +2 -0
- package/.expect/replays/87af45a5-dd8f-433a-8e5d-5ab136d653b9.html +286 -0
- package/.expect/replays/87af45a5-dd8f-433a-8e5d-5ab136d653b9.ndjson +3 -0
- package/.expect/replays/87af45a5-dd8f-433a-8e5d-5ab136d653b9.ndjson.js +2 -0
- package/.expect/replays/882a48e3-15b5-47fb-9f96-3e63c282557c.html +286 -0
- package/.expect/replays/882a48e3-15b5-47fb-9f96-3e63c282557c.ndjson +44 -0
- package/.expect/replays/882a48e3-15b5-47fb-9f96-3e63c282557c.ndjson.js +2 -0
- package/.expect/replays/8efca11f-3649-4433-a61c-f3b844aaa0b9.html +286 -0
- package/.expect/replays/8efca11f-3649-4433-a61c-f3b844aaa0b9.ndjson +33 -0
- package/.expect/replays/8efca11f-3649-4433-a61c-f3b844aaa0b9.ndjson.js +2 -0
- package/.expect/replays/8f563116-c926-4de3-9d16-3dfe33dd52b6.html +286 -0
- package/.expect/replays/8f563116-c926-4de3-9d16-3dfe33dd52b6.ndjson +12 -0
- package/.expect/replays/8f563116-c926-4de3-9d16-3dfe33dd52b6.ndjson.js +2 -0
- package/.expect/replays/9321eb59-9587-4819-80b0-b387c50aaaf4.html +286 -0
- package/.expect/replays/9321eb59-9587-4819-80b0-b387c50aaaf4.ndjson +10 -0
- package/.expect/replays/9321eb59-9587-4819-80b0-b387c50aaaf4.ndjson.js +2 -0
- package/.expect/replays/94cb0431-e2a6-4a8d-800a-6918adb25660.html +286 -0
- package/.expect/replays/94cb0431-e2a6-4a8d-800a-6918adb25660.ndjson +10 -0
- package/.expect/replays/94cb0431-e2a6-4a8d-800a-6918adb25660.ndjson.js +2 -0
- package/.expect/replays/94d30b76-3fb0-476a-93c5-c9acb88eb45a.html +286 -0
- package/.expect/replays/94d30b76-3fb0-476a-93c5-c9acb88eb45a.ndjson +43 -0
- package/.expect/replays/94d30b76-3fb0-476a-93c5-c9acb88eb45a.ndjson.js +2 -0
- package/.expect/replays/94da15c7-217f-4167-aad9-0ed7d69fb1a9.html +286 -0
- package/.expect/replays/94da15c7-217f-4167-aad9-0ed7d69fb1a9.ndjson +2 -0
- package/.expect/replays/94da15c7-217f-4167-aad9-0ed7d69fb1a9.ndjson.js +2 -0
- package/.expect/replays/9998db1c-b008-497f-8a13-1fc0eb6a8845.html +286 -0
- package/.expect/replays/9998db1c-b008-497f-8a13-1fc0eb6a8845.ndjson +31 -0
- package/.expect/replays/9998db1c-b008-497f-8a13-1fc0eb6a8845.ndjson.js +2 -0
- package/.expect/replays/9c54b7fe-d113-4d99-9df9-42af0779a176.html +286 -0
- package/.expect/replays/9c54b7fe-d113-4d99-9df9-42af0779a176.ndjson +52 -0
- package/.expect/replays/9c54b7fe-d113-4d99-9df9-42af0779a176.ndjson.js +2 -0
- package/.expect/replays/9d8b9d7f-2fad-44c8-92bc-5377adb4ca1b.html +286 -0
- package/.expect/replays/9d8b9d7f-2fad-44c8-92bc-5377adb4ca1b.ndjson +24 -0
- package/.expect/replays/9d8b9d7f-2fad-44c8-92bc-5377adb4ca1b.ndjson.js +2 -0
- package/.expect/replays/9f6d215a-17bd-44f8-be75-4f21c36cb7a5.html +286 -0
- package/.expect/replays/9f6d215a-17bd-44f8-be75-4f21c36cb7a5.ndjson +14 -0
- package/.expect/replays/9f6d215a-17bd-44f8-be75-4f21c36cb7a5.ndjson.js +2 -0
- package/.expect/replays/9fddc5ad-02e8-4f8e-96cf-c249444bf123.html +286 -0
- package/.expect/replays/9fddc5ad-02e8-4f8e-96cf-c249444bf123.ndjson +2 -0
- package/.expect/replays/9fddc5ad-02e8-4f8e-96cf-c249444bf123.ndjson.js +2 -0
- package/.expect/replays/a1e5b091-888f-43c5-95c3-c25f91f8925a.html +286 -0
- package/.expect/replays/a1e5b091-888f-43c5-95c3-c25f91f8925a.ndjson +12 -0
- package/.expect/replays/a1e5b091-888f-43c5-95c3-c25f91f8925a.ndjson.js +2 -0
- package/.expect/replays/a2e5372c-e459-4c47-8133-921303e7c74d.html +286 -0
- package/.expect/replays/a2e5372c-e459-4c47-8133-921303e7c74d.ndjson +2 -0
- package/.expect/replays/a2e5372c-e459-4c47-8133-921303e7c74d.ndjson.js +2 -0
- package/.expect/replays/a41a8fe3-4abc-4bde-bea0-526ef9d5c16f.html +286 -0
- package/.expect/replays/a41a8fe3-4abc-4bde-bea0-526ef9d5c16f.ndjson +16 -0
- package/.expect/replays/a41a8fe3-4abc-4bde-bea0-526ef9d5c16f.ndjson.js +2 -0
- package/.expect/replays/a726e14d-080c-4b30-b413-fcf6d14d0daf.html +286 -0
- package/.expect/replays/a726e14d-080c-4b30-b413-fcf6d14d0daf.ndjson +8 -0
- package/.expect/replays/a726e14d-080c-4b30-b413-fcf6d14d0daf.ndjson.js +2 -0
- package/.expect/replays/ab5651bb-3528-4b4b-809d-1e6d1fef2ade.html +286 -0
- package/.expect/replays/ab5651bb-3528-4b4b-809d-1e6d1fef2ade.ndjson +52 -0
- package/.expect/replays/ab5651bb-3528-4b4b-809d-1e6d1fef2ade.ndjson.js +2 -0
- package/.expect/replays/ac83d5ac-73c5-48f0-8d73-53f50151e4bf.html +286 -0
- package/.expect/replays/ac83d5ac-73c5-48f0-8d73-53f50151e4bf.ndjson +2 -0
- package/.expect/replays/ac83d5ac-73c5-48f0-8d73-53f50151e4bf.ndjson.js +2 -0
- package/.expect/replays/afeb4664-90ba-4525-9f4e-54349c5254f4.html +286 -0
- package/.expect/replays/afeb4664-90ba-4525-9f4e-54349c5254f4.ndjson +8 -0
- package/.expect/replays/afeb4664-90ba-4525-9f4e-54349c5254f4.ndjson.js +2 -0
- package/.expect/replays/b205a14f-ea04-41f7-b3f6-6a24881a4907.html +286 -0
- package/.expect/replays/b205a14f-ea04-41f7-b3f6-6a24881a4907.ndjson +44 -0
- package/.expect/replays/b205a14f-ea04-41f7-b3f6-6a24881a4907.ndjson.js +2 -0
- package/.expect/replays/b23eafd9-c876-4a66-a5e6-8d560672d5a8.html +286 -0
- package/.expect/replays/b23eafd9-c876-4a66-a5e6-8d560672d5a8.ndjson +84 -0
- package/.expect/replays/b23eafd9-c876-4a66-a5e6-8d560672d5a8.ndjson.js +2 -0
- package/.expect/replays/b4116451-32d0-4b85-a404-503bb4123815.html +286 -0
- package/.expect/replays/b4116451-32d0-4b85-a404-503bb4123815.ndjson +10 -0
- package/.expect/replays/b4116451-32d0-4b85-a404-503bb4123815.ndjson.js +2 -0
- package/.expect/replays/b649a6ef-45e3-49c2-bd02-284deb7ea9b1.html +286 -0
- package/.expect/replays/b649a6ef-45e3-49c2-bd02-284deb7ea9b1.ndjson +32 -0
- package/.expect/replays/b649a6ef-45e3-49c2-bd02-284deb7ea9b1.ndjson.js +2 -0
- package/.expect/replays/b8487d6d-87db-4453-9a87-f3ef57b9596a.html +286 -0
- package/.expect/replays/b8487d6d-87db-4453-9a87-f3ef57b9596a.ndjson +12 -0
- package/.expect/replays/b8487d6d-87db-4453-9a87-f3ef57b9596a.ndjson.js +2 -0
- package/.expect/replays/b9126d9e-93e9-44d1-901b-f4e4700a2ac7.html +286 -0
- package/.expect/replays/b9126d9e-93e9-44d1-901b-f4e4700a2ac7.ndjson +16 -0
- package/.expect/replays/b9126d9e-93e9-44d1-901b-f4e4700a2ac7.ndjson.js +2 -0
- package/.expect/replays/bc9ac26e-6915-466d-a250-61679c7d8785.html +286 -0
- package/.expect/replays/bc9ac26e-6915-466d-a250-61679c7d8785.ndjson +58 -0
- package/.expect/replays/bc9ac26e-6915-466d-a250-61679c7d8785.ndjson.js +2 -0
- package/.expect/replays/bf71f292-d0fa-4b38-88d2-838d631b4fd3.html +286 -0
- package/.expect/replays/bf71f292-d0fa-4b38-88d2-838d631b4fd3.ndjson +18 -0
- package/.expect/replays/bf71f292-d0fa-4b38-88d2-838d631b4fd3.ndjson.js +2 -0
- package/.expect/replays/c064a436-aa74-411c-b4ff-228e6016748c.html +286 -0
- package/.expect/replays/c064a436-aa74-411c-b4ff-228e6016748c.ndjson +14 -0
- package/.expect/replays/c064a436-aa74-411c-b4ff-228e6016748c.ndjson.js +2 -0
- package/.expect/replays/c293319a-56fc-47c2-be0a-efebab7e5547.html +286 -0
- package/.expect/replays/c293319a-56fc-47c2-be0a-efebab7e5547.ndjson +10 -0
- package/.expect/replays/c293319a-56fc-47c2-be0a-efebab7e5547.ndjson.js +2 -0
- package/.expect/replays/c48e7ccb-f40a-4d86-9ada-f9ac0f174809.html +286 -0
- package/.expect/replays/c48e7ccb-f40a-4d86-9ada-f9ac0f174809.ndjson +18 -0
- package/.expect/replays/c48e7ccb-f40a-4d86-9ada-f9ac0f174809.ndjson.js +2 -0
- package/.expect/replays/c4ec751f-4c2f-4ac4-83e1-9d53ebd275b0.html +286 -0
- package/.expect/replays/c4ec751f-4c2f-4ac4-83e1-9d53ebd275b0.ndjson +12 -0
- package/.expect/replays/c4ec751f-4c2f-4ac4-83e1-9d53ebd275b0.ndjson.js +2 -0
- package/.expect/replays/c5f8f2de-415c-4605-90e9-8a31286c1d33.html +286 -0
- package/.expect/replays/c5f8f2de-415c-4605-90e9-8a31286c1d33.ndjson +36 -0
- package/.expect/replays/c5f8f2de-415c-4605-90e9-8a31286c1d33.ndjson.js +2 -0
- package/.expect/replays/c92defec-c6f7-4334-89f4-d3b1010a592b.html +286 -0
- package/.expect/replays/c92defec-c6f7-4334-89f4-d3b1010a592b.ndjson +97 -0
- package/.expect/replays/c92defec-c6f7-4334-89f4-d3b1010a592b.ndjson.js +2 -0
- package/.expect/replays/ce024389-749b-4d9f-9cbe-d2add9b5d506.html +286 -0
- package/.expect/replays/ce024389-749b-4d9f-9cbe-d2add9b5d506.ndjson +8 -0
- package/.expect/replays/ce024389-749b-4d9f-9cbe-d2add9b5d506.ndjson.js +2 -0
- package/.expect/replays/d0106187-b170-4208-b6e2-1652906fb952.html +286 -0
- package/.expect/replays/d0106187-b170-4208-b6e2-1652906fb952.ndjson +52 -0
- package/.expect/replays/d0106187-b170-4208-b6e2-1652906fb952.ndjson.js +2 -0
- package/.expect/replays/d4aa55a2-9b5f-4eb5-b795-5324e5c5d7db.html +286 -0
- package/.expect/replays/d4aa55a2-9b5f-4eb5-b795-5324e5c5d7db.ndjson +84 -0
- package/.expect/replays/d4aa55a2-9b5f-4eb5-b795-5324e5c5d7db.ndjson.js +2 -0
- package/.expect/replays/d4fc939c-c97d-4125-95dc-a8745709e879.html +286 -0
- package/.expect/replays/d4fc939c-c97d-4125-95dc-a8745709e879.ndjson +2 -0
- package/.expect/replays/d4fc939c-c97d-4125-95dc-a8745709e879.ndjson.js +2 -0
- package/.expect/replays/d59474f3-6eee-4145-9252-ac56d7d634d1.html +286 -0
- package/.expect/replays/d59474f3-6eee-4145-9252-ac56d7d634d1.ndjson +46 -0
- package/.expect/replays/d59474f3-6eee-4145-9252-ac56d7d634d1.ndjson.js +2 -0
- package/.expect/replays/d842aee0-a2e0-45a4-84bb-02571ea704ef.html +286 -0
- package/.expect/replays/d842aee0-a2e0-45a4-84bb-02571ea704ef.ndjson +10 -0
- package/.expect/replays/d842aee0-a2e0-45a4-84bb-02571ea704ef.ndjson.js +2 -0
- package/.expect/replays/dbacab2e-6e47-4c2e-861b-881a3439cc61.html +286 -0
- package/.expect/replays/dbacab2e-6e47-4c2e-861b-881a3439cc61.ndjson +40 -0
- package/.expect/replays/dbacab2e-6e47-4c2e-861b-881a3439cc61.ndjson.js +2 -0
- package/.expect/replays/e47ad94c-1326-4e5f-9e36-9187b2475dc4.html +286 -0
- package/.expect/replays/e47ad94c-1326-4e5f-9e36-9187b2475dc4.ndjson +10 -0
- package/.expect/replays/e47ad94c-1326-4e5f-9e36-9187b2475dc4.ndjson.js +2 -0
- package/.expect/replays/e4e7c05e-0def-4eb4-80de-5c0abc6e9707.html +286 -0
- package/.expect/replays/e4e7c05e-0def-4eb4-80de-5c0abc6e9707.ndjson +32 -0
- package/.expect/replays/e4e7c05e-0def-4eb4-80de-5c0abc6e9707.ndjson.js +2 -0
- package/.expect/replays/e7fbb2f5-f5be-430f-b9d8-e9b5980c4e25.html +286 -0
- package/.expect/replays/e7fbb2f5-f5be-430f-b9d8-e9b5980c4e25.ndjson +30 -0
- package/.expect/replays/e7fbb2f5-f5be-430f-b9d8-e9b5980c4e25.ndjson.js +2 -0
- package/.expect/replays/ef25484d-6e02-4cde-bf19-7251a9ada2b3.html +286 -0
- package/.expect/replays/ef25484d-6e02-4cde-bf19-7251a9ada2b3.ndjson +37 -0
- package/.expect/replays/ef25484d-6e02-4cde-bf19-7251a9ada2b3.ndjson.js +2 -0
- package/.expect/replays/f114ddaa-f891-4be1-b626-eaeeba692e0f.html +286 -0
- package/.expect/replays/f114ddaa-f891-4be1-b626-eaeeba692e0f.ndjson +12 -0
- package/.expect/replays/f114ddaa-f891-4be1-b626-eaeeba692e0f.ndjson.js +2 -0
- package/.expect/replays/f39c87c6-34c7-4b81-8350-a644e309430f.html +286 -0
- package/.expect/replays/f39c87c6-34c7-4b81-8350-a644e309430f.ndjson +8 -0
- package/.expect/replays/f39c87c6-34c7-4b81-8350-a644e309430f.ndjson.js +2 -0
- package/.expect/replays/f6484a4f-c647-4f78-9a2e-f41f00683c15.html +286 -0
- package/.expect/replays/f6484a4f-c647-4f78-9a2e-f41f00683c15.ndjson +14 -0
- package/.expect/replays/f6484a4f-c647-4f78-9a2e-f41f00683c15.ndjson.js +2 -0
- package/.turbo/turbo-build.log +22 -0
- package/.turbo/turbo-check.log +6 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +12 -0
- package/LICENSE +110 -0
- package/README.md +536 -0
- package/dist/constants-DFJAD4-F.mjs +152 -0
- package/dist/constants-DFJAD4-F.mjs.map +1 -0
- package/dist/effect.d.mts +30 -0
- package/dist/effect.d.mts.map +1 -0
- package/dist/effect.mjs +2 -0
- package/dist/index.d.mts +20 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +279 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types-0J0EwTM4.d.mts +124 -0
- package/dist/types-0J0EwTM4.d.mts.map +1 -0
- package/package.json +46 -0
- package/src/build-instruction.ts +35 -0
- package/src/config.ts +15 -0
- package/src/constants.ts +2 -0
- package/src/effect.ts +14 -0
- package/src/errors.ts +17 -0
- package/src/expect.ts +432 -0
- package/src/index.ts +23 -0
- package/src/layers.ts +14 -0
- package/src/result-builder.ts +184 -0
- package/src/test-run.ts +19 -0
- package/src/tool.ts +26 -0
- package/src/types.ts +98 -0
- package/tests/build-instruction.test.ts +62 -0
- package/tests/config.test.ts +44 -0
- package/tests/e2e.ts +81 -0
- package/tests/examples.test.ts +44 -0
- package/tests/expect.test.ts +143 -0
- package/tests/fixtures/fixture-server.ts +111 -0
- package/tests/result-builder.test.ts +292 -0
- package/tests/test-run.test.ts +95 -0
- package/tests/tool.test.ts +60 -0
- package/tsconfig.json +9 -0
- package/vite.config.ts +13 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { describe, it, expect } from "vite-plus/test";
|
|
2
|
+
import { Option } from "effect";
|
|
3
|
+
import {
|
|
4
|
+
ExecutedTestPlan,
|
|
5
|
+
TestPlan,
|
|
6
|
+
TestPlanStep,
|
|
7
|
+
StepId,
|
|
8
|
+
PlanId,
|
|
9
|
+
ChangesFor,
|
|
10
|
+
RunStarted,
|
|
11
|
+
StepStarted,
|
|
12
|
+
StepCompleted,
|
|
13
|
+
StepFailed,
|
|
14
|
+
StepSkipped,
|
|
15
|
+
RunFinished,
|
|
16
|
+
ToolResult,
|
|
17
|
+
} from "@expect/shared/models";
|
|
18
|
+
import {
|
|
19
|
+
buildStepResult,
|
|
20
|
+
buildTestResult,
|
|
21
|
+
diffEvents,
|
|
22
|
+
extractArtifacts,
|
|
23
|
+
} from "../src/result-builder";
|
|
24
|
+
|
|
25
|
+
const NO_ARTIFACTS = { recordingPath: undefined, screenshotPaths: [] as string[] };
|
|
26
|
+
|
|
27
|
+
const makeStep = (
|
|
28
|
+
overrides: Partial<{
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
status: "pending" | "active" | "passed" | "failed" | "skipped";
|
|
32
|
+
summary: string;
|
|
33
|
+
}> = {},
|
|
34
|
+
): TestPlanStep =>
|
|
35
|
+
new TestPlanStep({
|
|
36
|
+
id: StepId.makeUnsafe(overrides.id ?? "step-1"),
|
|
37
|
+
title: overrides.title ?? "test step",
|
|
38
|
+
instruction: "test instruction",
|
|
39
|
+
expectedOutcome: "expected",
|
|
40
|
+
routeHint: Option.none(),
|
|
41
|
+
status: overrides.status ?? "pending",
|
|
42
|
+
summary: overrides.summary ? Option.some(overrides.summary) : Option.none(),
|
|
43
|
+
startedAt: Option.none(),
|
|
44
|
+
endedAt: Option.none(),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const makePlan = (steps: TestPlanStep[] = []): TestPlan =>
|
|
48
|
+
new TestPlan({
|
|
49
|
+
id: PlanId.makeUnsafe("plan-1"),
|
|
50
|
+
changesFor: ChangesFor.makeUnsafe({ _tag: "WorkingTree" }),
|
|
51
|
+
currentBranch: "main",
|
|
52
|
+
diffPreview: "",
|
|
53
|
+
fileStats: [],
|
|
54
|
+
instruction: "test",
|
|
55
|
+
baseUrl: Option.none(),
|
|
56
|
+
isHeadless: true,
|
|
57
|
+
cookieBrowserKeys: [],
|
|
58
|
+
testCoverage: Option.none(),
|
|
59
|
+
title: "Test Plan",
|
|
60
|
+
rationale: "testing",
|
|
61
|
+
steps,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const makeExecuted = (
|
|
65
|
+
steps: TestPlanStep[] = [],
|
|
66
|
+
events: readonly (typeof import("@expect/shared/models").ExecutionEvent.Type)[] = [],
|
|
67
|
+
): ExecutedTestPlan => {
|
|
68
|
+
const plan = makePlan(steps);
|
|
69
|
+
return new ExecutedTestPlan({ ...plan, steps, events });
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
describe("buildStepResult", () => {
|
|
73
|
+
it("maps passed step", () => {
|
|
74
|
+
const step = makeStep({ status: "passed", summary: "All good" });
|
|
75
|
+
const result = buildStepResult(step, [], 0);
|
|
76
|
+
expect(result.status).toBe("passed");
|
|
77
|
+
expect(result.summary).toBe("All good");
|
|
78
|
+
expect(result.title).toBe("test step");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("maps failed step", () => {
|
|
82
|
+
const step = makeStep({ status: "failed", summary: "Something broke" });
|
|
83
|
+
const result = buildStepResult(step, [], 0);
|
|
84
|
+
expect(result.status).toBe("failed");
|
|
85
|
+
expect(result.summary).toBe("Something broke");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("maps skipped step to failed", () => {
|
|
89
|
+
const step = makeStep({ status: "skipped", summary: "Not applicable" });
|
|
90
|
+
const result = buildStepResult(step, [], 0);
|
|
91
|
+
expect(result.status).toBe("failed");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("maps pending step", () => {
|
|
95
|
+
const step = makeStep({ status: "pending" });
|
|
96
|
+
const result = buildStepResult(step, [], 0);
|
|
97
|
+
expect(result.status).toBe("pending");
|
|
98
|
+
expect(result.summary).toBe("");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("maps active step to pending", () => {
|
|
102
|
+
const step = makeStep({ status: "active" });
|
|
103
|
+
const result = buildStepResult(step, [], 0);
|
|
104
|
+
expect(result.status).toBe("pending");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("associates screenshot path by index", () => {
|
|
108
|
+
const step = makeStep({ status: "passed", summary: "ok" });
|
|
109
|
+
const result = buildStepResult(step, ["/tmp/s0.png", "/tmp/s1.png"], 1);
|
|
110
|
+
expect(result.screenshotPath).toBe("/tmp/s1.png");
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("buildTestResult", () => {
|
|
115
|
+
it("returns passed when all steps passed", () => {
|
|
116
|
+
const executed = makeExecuted([
|
|
117
|
+
makeStep({ id: "s1", status: "passed", summary: "ok" }),
|
|
118
|
+
makeStep({ id: "s2", status: "passed", summary: "ok" }),
|
|
119
|
+
]);
|
|
120
|
+
const result = buildTestResult(
|
|
121
|
+
executed,
|
|
122
|
+
"http://localhost:3000",
|
|
123
|
+
Date.now() - 1000,
|
|
124
|
+
NO_ARTIFACTS,
|
|
125
|
+
);
|
|
126
|
+
expect(result.status).toBe("passed");
|
|
127
|
+
expect(result.errors).toHaveLength(0);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("returns failed when any step failed", () => {
|
|
131
|
+
const executed = makeExecuted([
|
|
132
|
+
makeStep({ id: "s1", status: "passed", summary: "ok" }),
|
|
133
|
+
makeStep({ id: "s2", status: "failed", summary: "broken" }),
|
|
134
|
+
]);
|
|
135
|
+
const result = buildTestResult(executed, "http://localhost:3000", Date.now(), NO_ARTIFACTS);
|
|
136
|
+
expect(result.status).toBe("failed");
|
|
137
|
+
expect(result.errors).toHaveLength(1);
|
|
138
|
+
expect(result.errors[0].summary).toBe("broken");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("returns pending when steps are still pending", () => {
|
|
142
|
+
const executed = makeExecuted([
|
|
143
|
+
makeStep({ id: "s1", status: "passed", summary: "ok" }),
|
|
144
|
+
makeStep({ id: "s2", status: "pending" }),
|
|
145
|
+
]);
|
|
146
|
+
const result = buildTestResult(executed, "http://localhost:3000", Date.now(), NO_ARTIFACTS);
|
|
147
|
+
expect(result.status).toBe("pending");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("returns pending when no steps exist", () => {
|
|
151
|
+
const executed = makeExecuted();
|
|
152
|
+
const result = buildTestResult(executed, "http://localhost:3000", Date.now(), NO_ARTIFACTS);
|
|
153
|
+
expect(result.status).toBe("pending");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("errors equals steps filtered by failed", () => {
|
|
157
|
+
const executed = makeExecuted([
|
|
158
|
+
makeStep({ id: "s1", status: "passed", summary: "ok" }),
|
|
159
|
+
makeStep({ id: "s2", status: "failed", summary: "err1" }),
|
|
160
|
+
makeStep({ id: "s3", status: "failed", summary: "err2" }),
|
|
161
|
+
]);
|
|
162
|
+
const result = buildTestResult(executed, "http://localhost:3000", Date.now(), NO_ARTIFACTS);
|
|
163
|
+
expect(result.errors).toHaveLength(2);
|
|
164
|
+
expect(result.errors.map((error) => error.summary)).toEqual(["err1", "err2"]);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("includes url", () => {
|
|
168
|
+
const executed = makeExecuted();
|
|
169
|
+
const result = buildTestResult(
|
|
170
|
+
executed,
|
|
171
|
+
"http://localhost:3000/login",
|
|
172
|
+
Date.now(),
|
|
173
|
+
NO_ARTIFACTS,
|
|
174
|
+
);
|
|
175
|
+
expect(result.url).toBe("http://localhost:3000/login");
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("includes recordingPath from artifacts", () => {
|
|
179
|
+
const executed = makeExecuted();
|
|
180
|
+
const result = buildTestResult(executed, "http://localhost:3000", Date.now(), {
|
|
181
|
+
recordingPath: "/tmp/replay.ndjson",
|
|
182
|
+
screenshotPaths: [],
|
|
183
|
+
});
|
|
184
|
+
expect(result.recordingPath).toBe("/tmp/replay.ndjson");
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe("extractArtifacts", () => {
|
|
189
|
+
it("returns empty when no close event", () => {
|
|
190
|
+
const result = extractArtifacts([]);
|
|
191
|
+
expect(result.recordingPath).toBeUndefined();
|
|
192
|
+
expect(result.screenshotPaths).toHaveLength(0);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("extracts recording path from close result", () => {
|
|
196
|
+
const events = [
|
|
197
|
+
new ToolResult({
|
|
198
|
+
toolName: "close",
|
|
199
|
+
result: "rrweb replay: /tmp/session.ndjson\nScreenshot: /tmp/s0.png",
|
|
200
|
+
isError: false,
|
|
201
|
+
}),
|
|
202
|
+
];
|
|
203
|
+
const result = extractArtifacts(events);
|
|
204
|
+
expect(result.recordingPath).toBe("/tmp/session.ndjson");
|
|
205
|
+
expect(result.screenshotPaths).toEqual(["/tmp/s0.png"]);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe("diffEvents", () => {
|
|
210
|
+
const plan = makePlan([makeStep({ id: "s1" })]);
|
|
211
|
+
const startedAt = Date.now();
|
|
212
|
+
|
|
213
|
+
it("emits run:started for RunStarted event", () => {
|
|
214
|
+
const events = [new RunStarted({ plan })];
|
|
215
|
+
const executed = makeExecuted(plan.steps as TestPlanStep[], events);
|
|
216
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
217
|
+
expect(result).toHaveLength(1);
|
|
218
|
+
expect(result[0].type).toBe("run:started");
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("emits step:started for StepStarted event", () => {
|
|
222
|
+
const events = [new StepStarted({ stepId: StepId.makeUnsafe("s1"), title: "test step" })];
|
|
223
|
+
const executed = makeExecuted(plan.steps as TestPlanStep[], events);
|
|
224
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
225
|
+
expect(result).toHaveLength(1);
|
|
226
|
+
expect(result[0].type).toBe("step:started");
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("emits step:passed for StepCompleted event", () => {
|
|
230
|
+
const completedStep = makeStep({ id: "s1", status: "passed", summary: "done" });
|
|
231
|
+
const events = [new StepCompleted({ stepId: StepId.makeUnsafe("s1"), summary: "done" })];
|
|
232
|
+
const executed = makeExecuted([completedStep], events);
|
|
233
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
234
|
+
expect(result).toHaveLength(1);
|
|
235
|
+
expect(result[0].type).toBe("step:passed");
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("emits step:failed for StepFailed event", () => {
|
|
239
|
+
const failedStep = makeStep({ id: "s1", status: "failed", summary: "broken" });
|
|
240
|
+
const events = [new StepFailed({ stepId: StepId.makeUnsafe("s1"), message: "broken" })];
|
|
241
|
+
const executed = makeExecuted([failedStep], events);
|
|
242
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
243
|
+
expect(result).toHaveLength(1);
|
|
244
|
+
expect(result[0].type).toBe("step:failed");
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("emits step:skipped for StepSkipped event", () => {
|
|
248
|
+
const skippedStep = makeStep({ id: "s1", status: "skipped", summary: "not needed" });
|
|
249
|
+
const events = [new StepSkipped({ stepId: StepId.makeUnsafe("s1"), reason: "not applicable" })];
|
|
250
|
+
const executed = makeExecuted([skippedStep], events);
|
|
251
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
252
|
+
expect(result).toHaveLength(1);
|
|
253
|
+
expect(result[0].type).toBe("step:skipped");
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("emits completed for RunFinished event", () => {
|
|
257
|
+
const events = [new RunFinished({ status: "passed", summary: "All passed" })];
|
|
258
|
+
const executed = makeExecuted(
|
|
259
|
+
[makeStep({ id: "s1", status: "passed", summary: "ok" })],
|
|
260
|
+
events,
|
|
261
|
+
);
|
|
262
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
263
|
+
expect(result).toHaveLength(1);
|
|
264
|
+
expect(result[0].type).toBe("completed");
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("emits screenshot for screenshot ToolResult", () => {
|
|
268
|
+
const events = [
|
|
269
|
+
new ToolResult({
|
|
270
|
+
toolName: "browser__screenshot",
|
|
271
|
+
result: "/tmp/screenshot-0.png",
|
|
272
|
+
isError: false,
|
|
273
|
+
}),
|
|
274
|
+
];
|
|
275
|
+
const executed = makeExecuted([], events);
|
|
276
|
+
const result = diffEvents([], events, executed, "http://localhost:3000", startedAt);
|
|
277
|
+
expect(result).toHaveLength(1);
|
|
278
|
+
expect(result[0].type).toBe("screenshot");
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it("only emits new events since previous snapshot", () => {
|
|
282
|
+
const event1 = new StepStarted({ stepId: StepId.makeUnsafe("s1"), title: "step 1" });
|
|
283
|
+
const event2 = new StepCompleted({ stepId: StepId.makeUnsafe("s1"), summary: "done" });
|
|
284
|
+
const allEvents = [event1, event2];
|
|
285
|
+
const completedStep = makeStep({ id: "s1", status: "passed", summary: "done" });
|
|
286
|
+
const executed = makeExecuted([completedStep], allEvents);
|
|
287
|
+
|
|
288
|
+
const result = diffEvents([event1], allEvents, executed, "http://localhost:3000", startedAt);
|
|
289
|
+
expect(result).toHaveLength(1);
|
|
290
|
+
expect(result[0].type).toBe("step:passed");
|
|
291
|
+
});
|
|
292
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { describe, it, expect } from "vite-plus/test";
|
|
2
|
+
import { createTestRun } from "../src/test-run";
|
|
3
|
+
import type { TestResult, TestEvent } from "../src/types";
|
|
4
|
+
|
|
5
|
+
const makeResult = (status: "passed" | "failed" = "passed"): TestResult => ({
|
|
6
|
+
status,
|
|
7
|
+
url: "http://localhost:3000",
|
|
8
|
+
duration: 1000,
|
|
9
|
+
steps: [],
|
|
10
|
+
errors: [],
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe("createTestRun", () => {
|
|
14
|
+
it("await resolves to TestResult", async () => {
|
|
15
|
+
const result = makeResult();
|
|
16
|
+
const run = createTestRun({
|
|
17
|
+
promise: Promise.resolve(result),
|
|
18
|
+
subscribe: () => (async function* () {})(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const awaited = await run;
|
|
22
|
+
expect(awaited).toBe(result);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("for await yields TestEvents", async () => {
|
|
26
|
+
const events: TestEvent[] = [
|
|
27
|
+
{ type: "step:started", title: "step 1" },
|
|
28
|
+
{
|
|
29
|
+
type: "step:passed",
|
|
30
|
+
step: { title: "step 1", status: "passed", summary: "ok", duration: 100 },
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
let index = 0;
|
|
35
|
+
const run = createTestRun({
|
|
36
|
+
promise: Promise.resolve(makeResult()),
|
|
37
|
+
subscribe: () => {
|
|
38
|
+
const iterator: AsyncIterableIterator<TestEvent> = {
|
|
39
|
+
async next() {
|
|
40
|
+
if (index >= events.length) return { done: true, value: undefined };
|
|
41
|
+
const event = events[index];
|
|
42
|
+
index++;
|
|
43
|
+
return { done: false, value: event };
|
|
44
|
+
},
|
|
45
|
+
[Symbol.asyncIterator]() {
|
|
46
|
+
return this;
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
return iterator;
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const collected: TestEvent[] = [];
|
|
54
|
+
for await (const event of run) {
|
|
55
|
+
collected.push(event);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
expect(collected).toHaveLength(2);
|
|
59
|
+
expect(collected[0].type).toBe("step:started");
|
|
60
|
+
expect(collected[1].type).toBe("step:passed");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("iterating and awaiting the same TestRun both work", async () => {
|
|
64
|
+
const result = makeResult();
|
|
65
|
+
const events: TestEvent[] = [{ type: "step:started", title: "step 1" }];
|
|
66
|
+
|
|
67
|
+
let index = 0;
|
|
68
|
+
const run = createTestRun({
|
|
69
|
+
promise: Promise.resolve(result),
|
|
70
|
+
subscribe: () => {
|
|
71
|
+
const iterator: AsyncIterableIterator<TestEvent> = {
|
|
72
|
+
async next() {
|
|
73
|
+
if (index >= events.length) return { done: true, value: undefined };
|
|
74
|
+
const event = events[index];
|
|
75
|
+
index++;
|
|
76
|
+
return { done: false, value: event };
|
|
77
|
+
},
|
|
78
|
+
[Symbol.asyncIterator]() {
|
|
79
|
+
return this;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
return iterator;
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const collected: TestEvent[] = [];
|
|
87
|
+
for await (const event of run) {
|
|
88
|
+
collected.push(event);
|
|
89
|
+
}
|
|
90
|
+
expect(collected).toHaveLength(1);
|
|
91
|
+
|
|
92
|
+
const awaited = await run;
|
|
93
|
+
expect(awaited.status).toBe("passed");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from "vite-plus/test";
|
|
2
|
+
import { tool } from "../src/tool";
|
|
3
|
+
|
|
4
|
+
describe("tool", () => {
|
|
5
|
+
it("creates a tool with name, description, schema, handler", () => {
|
|
6
|
+
const handler = async (input: Record<string, unknown>) => `Created ${input.email}`;
|
|
7
|
+
const result = tool(
|
|
8
|
+
"create_user",
|
|
9
|
+
"Create a test user",
|
|
10
|
+
{ type: "object", properties: { email: { type: "string" } }, required: ["email"] },
|
|
11
|
+
handler,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(result.name).toBe("create_user");
|
|
15
|
+
expect(result.description).toBe("Create a test user");
|
|
16
|
+
expect(result.inputSchema).toEqual({
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: { email: { type: "string" } },
|
|
19
|
+
required: ["email"],
|
|
20
|
+
});
|
|
21
|
+
expect(result.handler).toBe(handler);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("handler receives parsed input and returns string", async () => {
|
|
25
|
+
const myTool = tool(
|
|
26
|
+
"greet",
|
|
27
|
+
"Greet user",
|
|
28
|
+
{ type: "object", properties: { name: { type: "string" } } },
|
|
29
|
+
async (input) => `Hello ${input.name}`,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const result = await myTool.handler({ name: "Alice" });
|
|
33
|
+
expect(result).toBe("Hello Alice");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("tools compose via arrays", () => {
|
|
37
|
+
const toolA = tool("a", "tool a", {}, async () => "a");
|
|
38
|
+
const toolB = tool("b", "tool b", {}, async () => "b");
|
|
39
|
+
const combined = [toolA, toolB];
|
|
40
|
+
|
|
41
|
+
expect(combined).toHaveLength(2);
|
|
42
|
+
expect(combined[0].name).toBe("a");
|
|
43
|
+
expect(combined[1].name).toBe("b");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("extracts JSON Schema from StandardJSONSchemaV1", () => {
|
|
47
|
+
const standardSchema = {
|
|
48
|
+
"~standard": {
|
|
49
|
+
version: 1 as const,
|
|
50
|
+
vendor: "test",
|
|
51
|
+
jsonSchema: {
|
|
52
|
+
input: () => ({ type: "object", properties: { id: { type: "string" } } }),
|
|
53
|
+
output: () => ({ type: "object", properties: { id: { type: "string" } } }),
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
const result = tool("test", "test tool", standardSchema, async () => "ok");
|
|
58
|
+
expect(result.inputSchema).toEqual({ type: "object", properties: { id: { type: "string" } } });
|
|
59
|
+
});
|
|
60
|
+
});
|
package/tsconfig.json
ADDED
package/vite.config.ts
ADDED