feat: collection CLI runner with iterations and data feed (#4475)

Co-authored-by: Shoban <mshobanr@ford.com>
Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
shobanrajm
2024-11-22 22:38:51 +05:30
committed by GitHub
parent e040f44245
commit b78cd57884
16 changed files with 705 additions and 320 deletions

View File

@@ -3,6 +3,92 @@
exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_id> --env <file_path_or_id> --reporter-junit [path] > Generates a JUnit report at the default path 1`] = `
"<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="76" failures="2" errors="66" time="time">
<testsuite name="test-junit-report-export/assertions/error" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be null" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be null"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be undefined" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/success" time="time" timestamp="timestamp" tests="5" failures="0" errors="0">
<testcase name="Status code is 200 - Expected '200' to be '200'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'application/json, text/plain, */*,image/webp' to be 'application/json, text/plain, */*,image/webp'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'echo.hoppscotch.io' to be 'echo.hoppscotch.io'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'undefined' to be 'undefined'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Status code is 2xx - Expected '200' to be 200-level status" classname="test-junit-report-export/assertions/success"/>
</testsuite>
<testsuite name="test-junit-report-export/assertions/failure" time="time" timestamp="timestamp" tests="5" failures="2" errors="0">
<testcase name="Simulating failure - Status code is 200 - Expected '200' to not be '200'" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be '200'"/>
</testcase>
<testcase name="Simulating failure - Check headers - Expected 'application/json, text/plain, */*,image/webp' to not be 'application/json, text/plain, */*'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'echo.hoppscotch.io' to not be 'httpbin.org'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'undefined' to not be 'value'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Status code is 2xx - Expected '200' to not be 200-level status" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be 200-level status"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/request-level-errors/invalid-url" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<system-err><![CDATA[
REQUEST_ERROR - TypeError: Invalid URL]]></system-err>
@@ -150,98 +236,98 @@ exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_i
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/error" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be null" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be null"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be undefined" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/success" time="time" timestamp="timestamp" tests="5" failures="0" errors="0">
<testcase name="Status code is 200 - Expected '200' to be '200'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'application/json, text/plain, */*,image/webp' to be 'application/json, text/plain, */*,image/webp'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'echo.hoppscotch.io' to be 'echo.hoppscotch.io'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'undefined' to be 'undefined'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Status code is 2xx - Expected '200' to be 200-level status" classname="test-junit-report-export/assertions/success"/>
</testsuite>
<testsuite name="test-junit-report-export/assertions/failure" time="time" timestamp="timestamp" tests="5" failures="2" errors="0">
<testcase name="Simulating failure - Status code is 200 - Expected '200' to not be '200'" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be '200'"/>
</testcase>
<testcase name="Simulating failure - Check headers - Expected 'application/json, text/plain, */*,image/webp' to not be 'application/json, text/plain, */*'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'echo.hoppscotch.io' to not be 'httpbin.org'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'undefined' to not be 'value'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Status code is 2xx - Expected '200' to not be 200-level status" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be 200-level status"/>
</testcase>
</testsuite>
</testsuites>"
`;
exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_id> --env <file_path_or_id> --reporter-junit [path] > Generates a JUnit report at the specified path 1`] = `
"<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="76" failures="2" errors="66" time="time">
<testsuite name="test-junit-report-export/assertions/error" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be null" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be null"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be undefined" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/success" time="time" timestamp="timestamp" tests="5" failures="0" errors="0">
<testcase name="Status code is 200 - Expected '200' to be '200'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'application/json, text/plain, */*,image/webp' to be 'application/json, text/plain, */*,image/webp'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'echo.hoppscotch.io' to be 'echo.hoppscotch.io'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'undefined' to be 'undefined'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Status code is 2xx - Expected '200' to be 200-level status" classname="test-junit-report-export/assertions/success"/>
</testsuite>
<testsuite name="test-junit-report-export/assertions/failure" time="time" timestamp="timestamp" tests="5" failures="2" errors="0">
<testcase name="Simulating failure - Status code is 200 - Expected '200' to not be '200'" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be '200'"/>
</testcase>
<testcase name="Simulating failure - Check headers - Expected 'application/json, text/plain, */*,image/webp' to not be 'application/json, text/plain, */*'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'echo.hoppscotch.io' to not be 'httpbin.org'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'undefined' to not be 'value'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Status code is 2xx - Expected '200' to not be 200-level status" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be 200-level status"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/request-level-errors/invalid-url" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<system-err><![CDATA[
REQUEST_ERROR - TypeError: Invalid URL]]></system-err>
@@ -389,92 +475,6 @@ exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_i
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/error" time="time" timestamp="timestamp" tests="22" failures="0" errors="22">
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeLevelxxx()\` error scenarios - Expected 200-level status but could not parse value 'foo'" classname="test-junit-report-export/assertions/error">
<error message="Expected 200-level status but could not parse value 'foo'"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toBeType()\` error scenarios - Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;" classname="test-junit-report-export/assertions/error">
<error message="Argument for toBeType should be &quot;string&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;object&quot;, &quot;undefined&quot;, &quot;bigint&quot;, &quot;symbol&quot; or &quot;function&quot;"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Expected toHaveLength to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toHaveLength to be called for an array or string"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toHaveLength()\` error scenarios - Argument for toHaveLength should be a number" classname="test-junit-report-export/assertions/error">
<error message="Argument for toHaveLength should be a number"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Expected toInclude to be called for an array or string" classname="test-junit-report-export/assertions/error">
<error message="Expected toInclude to be called for an array or string"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be null" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be null"/>
</testcase>
<testcase name="\`toInclude() error scenarios\` - Argument for toInclude should not be undefined" classname="test-junit-report-export/assertions/error">
<error message="Argument for toInclude should not be undefined"/>
</testcase>
</testsuite>
<testsuite name="test-junit-report-export/assertions/success" time="time" timestamp="timestamp" tests="5" failures="0" errors="0">
<testcase name="Status code is 200 - Expected '200' to be '200'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'application/json, text/plain, */*,image/webp' to be 'application/json, text/plain, */*,image/webp'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'echo.hoppscotch.io' to be 'echo.hoppscotch.io'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Check headers - Expected 'undefined' to be 'undefined'" classname="test-junit-report-export/assertions/success"/>
<testcase name="Status code is 2xx - Expected '200' to be 200-level status" classname="test-junit-report-export/assertions/success"/>
</testsuite>
<testsuite name="test-junit-report-export/assertions/failure" time="time" timestamp="timestamp" tests="5" failures="2" errors="0">
<testcase name="Simulating failure - Status code is 200 - Expected '200' to not be '200'" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be '200'"/>
</testcase>
<testcase name="Simulating failure - Check headers - Expected 'application/json, text/plain, */*,image/webp' to not be 'application/json, text/plain, */*'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'echo.hoppscotch.io' to not be 'httpbin.org'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Check headers - Expected 'undefined' to not be 'value'" classname="test-junit-report-export/assertions/failure"/>
<testcase name="Simulating failure - Status code is 2xx - Expected '200' to not be 200-level status" classname="test-junit-report-export/assertions/failure">
<failure type="AssertionFailure" message="Expected '200' to not be 200-level status"/>
</testcase>
</testsuite>
</testsuites>"
`;
@@ -501,14 +501,6 @@ exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_i
exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_id> --env <file_path_or_id> --reporter-junit [path] > Generates a JUnit report for a collection with authorization/headers set at the collection level 1`] = `
"<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="12" failures="0" errors="0" time="time">
<testsuite name="CollectionB/RequestA" time="time" timestamp="timestamp" tests="2" failures="0" errors="0">
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Set at root collection' to be 'Set at root collection'" classname="CollectionB/RequestA"/>
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Bearer BearerToken' to be 'Bearer BearerToken'" classname="CollectionB/RequestA"/>
</testsuite>
<testsuite name="CollectionB/FolderA/RequestB" time="time" timestamp="timestamp" tests="2" failures="0" errors="0">
<testcase name="Correctly inherits auth and headers from the parent folder - Expected 'Set at root collection' to be 'Set at root collection'" classname="CollectionB/FolderA/RequestB"/>
<testcase name="Correctly inherits auth and headers from the parent folder - Expected 'Bearer BearerToken' to be 'Bearer BearerToken'" classname="CollectionB/FolderA/RequestB"/>
</testsuite>
<testsuite name="CollectionA/RequestA" time="time" timestamp="timestamp" tests="2" failures="0" errors="0">
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Set at root collection' to be 'Set at root collection'" classname="CollectionA/RequestA"/>
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Bearer BearerToken' to be 'Bearer BearerToken'" classname="CollectionA/RequestA"/>
@@ -525,5 +517,13 @@ exports[`hopp test [options] <file_path_or_id> > Test\`hopp test <file_path_or_i
<testcase name="Overrides auth and headers set at the parent folder - Expected 'Overriden at RequestD' to be 'Overriden at RequestD'" classname="CollectionA/FolderA/FolderB/FolderC/RequestD"/>
<testcase name="Overrides auth and headers set at the parent folder - Expected 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=' to be 'Basic dXNlcm5hbWU6cGFzc3dvcmQ='" classname="CollectionA/FolderA/FolderB/FolderC/RequestD"/>
</testsuite>
<testsuite name="CollectionB/RequestA" time="time" timestamp="timestamp" tests="2" failures="0" errors="0">
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Set at root collection' to be 'Set at root collection'" classname="CollectionB/RequestA"/>
<testcase name="Correctly inherits auth and headers from the root collection - Expected 'Bearer BearerToken' to be 'Bearer BearerToken'" classname="CollectionB/RequestA"/>
</testsuite>
<testsuite name="CollectionB/FolderA/RequestB" time="time" timestamp="timestamp" tests="2" failures="0" errors="0">
<testcase name="Correctly inherits auth and headers from the parent folder - Expected 'Set at root collection' to be 'Set at root collection'" classname="CollectionB/FolderA/RequestB"/>
<testcase name="Correctly inherits auth and headers from the parent folder - Expected 'Bearer BearerToken' to be 'Bearer BearerToken'" classname="CollectionB/FolderA/RequestB"/>
</testsuite>
</testsuites>"
`;

View File

@@ -1,7 +1,7 @@
import { ExecException } from "child_process";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import fs from "fs";
import path from "path";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import { HoppErrorCode } from "../../../types/errors";
import { getErrorCode, getTestJsonFilePath, runCLI } from "../../utils";
@@ -181,6 +181,45 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
});
});
test("Ensures tests run in sequence order based on request path", async () => {
// Expected order of collection runs
const expectedOrder = [
"root-collection-request",
"folder-1/folder-1-request",
"folder-1/folder-11/folder-11-request",
"folder-1/folder-12/folder-12-request",
"folder-1/folder-13/folder-13-request",
"folder-2/folder-2-request",
"folder-2/folder-21/folder-21-request",
"folder-2/folder-22/folder-22-request",
"folder-2/folder-23/folder-23-request",
"folder-3/folder-3-request",
"folder-3/folder-31/folder-31-request",
"folder-3/folder-32/folder-32-request",
"folder-3/folder-33/folder-33-request",
];
const normalizePath = (path: string) => path.replace(/\\/g, "/");
const extractRunningOrder = (stdout: string): string[] =>
[...stdout.matchAll(/Running:.*?\/(.*?)\r?\n/g)].map(
([, path]) => normalizePath(path.replace(/\x1b\[\d+m/g, "")) // Remove ANSI codes and normalize paths
);
const args = `test ${getTestJsonFilePath(
"multiple-child-collections-auth-headers-coll.json",
"collection"
)}`;
const { stdout, error } = await runCLI(args);
// Verify the actual order matches the expected order
expect(extractRunningOrder(stdout)).toStrictEqual(expectedOrder);
// Ensure no errors occurred
expect(error).toBeNull();
});
describe("Test `hopp test <file_path_or_id> --env <file_path_or_id>` command:", () => {
describe("Supplied environment export file validations", () => {
describe("Argument parsing", () => {
@@ -235,12 +274,12 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
});
test("Successfully resolves values from the supplied environment export file", async () => {
const TESTS_PATH = getTestJsonFilePath(
const COLL_PATH = getTestJsonFilePath(
"env-flag-tests-coll.json",
"collection"
);
const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment");
const args = `test ${TESTS_PATH} --env ${ENV_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
@@ -251,23 +290,23 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"req-body-env-vars-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"req-body-env-vars-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
});
test("Works with short `-e` flag", async () => {
const TESTS_PATH = getTestJsonFilePath(
const COLL_PATH = getTestJsonFilePath(
"env-flag-tests-coll.json",
"collection"
);
const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment");
const args = `test ${TESTS_PATH} -e ${ENV_PATH}`;
const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
@@ -290,11 +329,8 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"secret-envs-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
"secret-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const ENV_PATH = getTestJsonFilePath("secret-envs.json", "environment");
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error, stdout } = await runCLI(args, { env });
@@ -310,11 +346,11 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"secret-envs-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"secret-supplied-values-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error, stdout } = await runCLI(args);
@@ -330,11 +366,11 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"secret-envs-persistence-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"secret-supplied-values-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error, stdout } = await runCLI(args);
@@ -349,12 +385,12 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"secret-envs-persistence-scripting-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"secret-envs-persistence-scripting-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
@@ -372,12 +408,12 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"request-vars-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"request-vars-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --env ${ENVS_PATH}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
const { error, stdout } = await runCLI(args, { env });
expect(stdout).toContain(
@@ -399,12 +435,12 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"aws-signature-auth-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"aws-signature-auth-envs.json",
"environment"
);
const args = `test ${COLL_PATH} -e ${ENVS_PATH}`;
const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
const { error } = await runCLI(args, { env });
expect(error).toBeNull();
@@ -417,14 +453,13 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"digest-auth-success-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"digest-auth-envs.json",
"environment"
);
const args = `test ${COLL_PATH} -e ${ENVS_PATH}`;
const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
});
});
@@ -434,12 +469,12 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"digest-auth-failure-coll.json",
"collection"
);
const ENVS_PATH = getTestJsonFilePath(
const ENV_PATH = getTestJsonFilePath(
"digest-auth-envs.json",
"environment"
);
const args = `test ${COLL_PATH} -e ${ENVS_PATH}`;
const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
const { error } = await runCLI(args);
expect(error).toBeTruthy();
@@ -583,11 +618,11 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
});
test("Supports specifying collection file path along with environment ID", async () => {
const TESTS_PATH = getTestJsonFilePath(
const COLL_PATH = getTestJsonFilePath(
"req-body-env-vars-coll.json",
"collection"
);
const args = `test ${TESTS_PATH} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
const args = `test ${COLL_PATH} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
@@ -605,7 +640,7 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
});
test("Supports specifying both collection and environment file paths", async () => {
const TESTS_PATH = getTestJsonFilePath(
const COLL_PATH = getTestJsonFilePath(
"req-body-env-vars-coll.json",
"collection"
);
@@ -613,7 +648,7 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
"req-body-env-vars-envs.json",
"environment"
);
const args = `test ${TESTS_PATH} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN}`;
const args = `test ${COLL_PATH} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN}`;
const { error } = await runCLI(args);
expect(error).toBeNull();
@@ -644,9 +679,10 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
const COLL_PATH = getTestJsonFilePath("passes-coll.json", "collection");
const invalidPath = process.platform === 'win32'
? 'Z:/non-existent-path/report.xml'
: '/non-existent/report.xml';
const invalidPath =
process.platform === "win32"
? "Z:/non-existent-path/report.xml"
: "/non-existent/report.xml";
const args = `test ${COLL_PATH} --reporter-junit ${invalidPath}`;
@@ -782,4 +818,139 @@ describe("hopp test [options] <file_path_or_id>", { timeout: 100000 }, () => {
expect(replaceDynamicValuesInStr(fileContents)).toMatchSnapshot();
});
});
describe("Test `hopp test <file> --iteration-count <no_of_iterations>` command:", () => {
const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
test("Errors with the code `INVALID_ARGUMENT` on not supplying an iteration count", async () => {
const args = `${VALID_TEST_ARGS} --iteration-count`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("INVALID_ARGUMENT");
});
test("Errors with the code `INVALID_ARGUMENT` on supplying an invalid iteration count", async () => {
const args = `${VALID_TEST_ARGS} --iteration-count NaN`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("INVALID_ARGUMENT");
});
test("Errors with the code `INVALID_ARGUMENT` on supplying an iteration count below `1`", async () => {
const args = `${VALID_TEST_ARGS} --iteration-count -5`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("INVALID_ARGUMENT");
});
test("Successfully executes all requests in the collection iteratively based on the specified iteration count", async () => {
const iterationCount = 3;
const args = `${VALID_TEST_ARGS} --iteration-count ${iterationCount}`;
const { error, stdout } = await runCLI(args);
// Logs iteration count in each pass
Array.from({ length: 3 }).forEach((_, idx) =>
expect(stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
);
expect(error).toBeNull();
});
test("Doesn't log iteration count if the value supplied is `1`", async () => {
const args = `${VALID_TEST_ARGS} --iteration-count 1`;
const { error, stdout } = await runCLI(args);
expect(stdout).not.include(`Iteration: 1/1`);
expect(error).toBeNull();
});
});
describe("Test `hopp test <file> --iteration-data <file_path>` command:", () => {
describe("Supplied data export file validations", () => {
const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
test("Errors with the code `INVALID_ARGUMENT` if no file is supplied", async () => {
const args = `${VALID_TEST_ARGS} --iteration-data`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("INVALID_ARGUMENT");
});
test("Errors with the code `INVALID_DATA_FILE_TYPE` if the supplied data file doesn't end with the `.csv` extension", async () => {
const args = `${VALID_TEST_ARGS} --iteration-data ${getTestJsonFilePath(
"notjson-coll.txt",
"collection"
)}`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("INVALID_DATA_FILE_TYPE");
});
test("Errors with the code `FILE_NOT_FOUND` if the supplied data export file doesn't exist", async () => {
const args = `${VALID_TEST_ARGS} --iteration-data notfound.csv`;
const { stderr } = await runCLI(args);
const out = getErrorCode(stderr);
expect(out).toBe<HoppErrorCode>("FILE_NOT_FOUND");
});
});
test("Prioritizes values from the supplied data export file over environment variables with relevant fallbacks for missing entries", async () => {
const COLL_PATH = getTestJsonFilePath(
"iteration-data-tests-coll.json",
"collection"
);
const ITERATION_DATA_PATH = getTestJsonFilePath(
"iteration-data-export.csv",
"environment"
);
const ENV_PATH = getTestJsonFilePath(
"iteration-data-envs.json",
"environment"
);
const args = `test ${COLL_PATH} --iteration-data ${ITERATION_DATA_PATH} -e ${ENV_PATH}`;
const { error, stdout } = await runCLI(args);
const iterationCount = 3;
// Even though iteration count is not supplied, it will be inferred from the iteration data size
Array.from({ length: iterationCount }).forEach((_, idx) =>
expect(stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
);
expect(error).toBeNull();
});
test("Iteration count takes priority if supplied instead of inferring from the iteration data size", async () => {
const COLL_PATH = getTestJsonFilePath(
"iteration-data-tests-coll.json",
"collection"
);
const ITERATION_DATA_PATH = getTestJsonFilePath(
"iteration-data-export.csv",
"environment"
);
const ENV_PATH = getTestJsonFilePath(
"iteration-data-envs.json",
"environment"
);
const iterationCount = 5;
const args = `test ${COLL_PATH} --iteration-data ${ITERATION_DATA_PATH} -e ${ENV_PATH} --iteration-count ${iterationCount}`;
const { error, stdout } = await runCLI(args);
Array.from({ length: iterationCount }).forEach((_, idx) =>
expect(stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
);
expect(error).toBeNull();
});
});
});

View File

@@ -0,0 +1,23 @@
{
"v": 1,
"name": "iteration-data-tests-coll",
"folders": [],
"requests": [
{
"v": "3",
"endpoint": "<<URL>>",
"name": "test1",
"params": [],
"headers": [],
"method": "POST",
"auth": { "authType": "none", "authActive": true },
"preRequestScript": "",
"testScript": "// Iteration data is prioritised over environment variables \n const { data, headers } = pw.response.body;\n pw.expect(headers['host']).toBe('echo.hoppscotch.io')\n // Falls back to environment variables for missing entries in data export\n pw.expect(data).toInclude('overriden-body-key-at-environment')\n pw.expect(data).toInclude('body_value')",
"body": {
"contentType": "application/json",
"body": "{\n \"<<BODY_KEY>>\":\"<<BODY_VALUE>>\"\n}"
},
"requestVariables": []
}
]
}

View File

@@ -0,0 +1,18 @@
{
"v": 0,
"name": "Iteration data environments",
"variables": [
{
"key": "URL",
"value": "https://httpbin.org/get"
},
{
"key": "BODY_KEY",
"value": "overriden-body-key-at-environment"
},
{
"key": "BODY_VALUE",
"value": "overriden-body-value-at-environment"
}
]
}

View File

@@ -0,0 +1,4 @@
URL,BODY_KEY,BODY_VALUE
https://echo.hoppscotch.io/1,,body_value1
https://echo.hoppscotch.io/2,,body_value2
https://echo.hoppscotch.io/3,,body_value3
1 URL BODY_KEY BODY_VALUE
2 https://echo.hoppscotch.io/1 body_value1
3 https://echo.hoppscotch.io/2 body_value2
4 https://echo.hoppscotch.io/3 body_value3

View File

@@ -1,7 +1,14 @@
import fs from "fs";
import { isSafeInteger } from "lodash-es";
import Papa from "papaparse";
import path from "path";
import { handleError } from "../handlers/error";
import { parseDelayOption } from "../options/test/delay";
import { parseEnvsData } from "../options/test/env";
import { IterationDataItem } from "../types/collections";
import { TestCmdEnvironmentOptions, TestCmdOptions } from "../types/commands";
import { error } from "../types/errors";
import { HoppEnvs } from "../types/request";
import { isHoppCLIError } from "../utils/checks";
import {
@@ -13,16 +20,79 @@ import { parseCollectionData } from "../utils/mutators";
export const test = (pathOrId: string, options: TestCmdOptions) => async () => {
try {
const delay = options.delay ? parseDelayOption(options.delay) : 0;
const { delay, env, iterationCount, iterationData, reporterJunit } =
options;
const envs = options.env
if (
iterationCount !== undefined &&
(iterationCount < 1 || !isSafeInteger(iterationCount))
) {
throw error({
code: "INVALID_ARGUMENT",
data: "The value must be a positive integer",
});
}
const resolvedDelay = delay ? parseDelayOption(delay) : 0;
const envs = env
? await parseEnvsData(options as TestCmdEnvironmentOptions)
: <HoppEnvs>{ global: [], selected: [] };
let parsedIterationData: unknown[] | null = null;
let transformedIterationData: IterationDataItem[][] | undefined;
const collections = await parseCollectionData(pathOrId, options);
const report = await collectionsRunner({ collections, envs, delay });
const hasSucceeded = collectionsRunnerResult(report, options.reporterJunit);
if (iterationData) {
// Check file existence
if (!fs.existsSync(iterationData)) {
throw error({ code: "FILE_NOT_FOUND", path: iterationData });
}
// Check the file extension
if (path.extname(iterationData) !== ".csv") {
throw error({
code: "INVALID_DATA_FILE_TYPE",
data: iterationData,
});
}
const csvData = fs.readFileSync(iterationData, "utf8");
parsedIterationData = Papa.parse(csvData, { header: true }).data;
// Transform data into the desired format
transformedIterationData = parsedIterationData
.map((item) => {
const iterationDataItem = item as Record<string, unknown>;
const keys = Object.keys(iterationDataItem);
return (
keys
// Ignore keys with empty string values
.filter((key) => iterationDataItem[key] !== "")
.map(
(key) =>
<IterationDataItem>{
key: key,
value: iterationDataItem[key],
secret: false,
}
)
);
})
// Ignore items that result in an empty array
.filter((item) => item.length > 0);
}
const report = await collectionsRunner({
collections,
envs,
delay: resolvedDelay,
iterationData: transformedIterationData,
iterationCount,
});
const hasSucceeded = collectionsRunnerResult(report, reporterJunit);
collectionsRunnerExit(hasSucceeded);
} catch (e) {

View File

@@ -65,6 +65,9 @@ export const handleError = <T extends HoppErrorCode>(error: HoppError<T>) => {
case "INVALID_FILE_TYPE":
ERROR_MSG = `Please provide file of extension type .json: ${error.data}`;
break;
case "INVALID_DATA_FILE_TYPE":
ERROR_MSG = `Please provide file of extension type .csv: ${error.data}`;
break;
case "REQUEST_ERROR":
case "TEST_SCRIPT_ERROR":
case "PRE_REQUEST_SCRIPT_ERROR":

View File

@@ -69,6 +69,15 @@ program
"--reporter-junit [path]",
"generate JUnit report optionally specifying the path"
)
.option(
"--iteration-count <no_of_iterations>",
"number of iterations to run the test",
parseInt
)
.option(
"--iteration-data <file_path>",
"path to a CSV file for data-driven testing"
)
.allowExcessArguments(false)
.allowUnknownOption(false)
.description("running hoppscotch collection.json file")

View File

@@ -1,10 +1,15 @@
import { HoppCollection } from "@hoppscotch/data";
import { HoppEnvs } from "./request";
import { HoppEnvPair, HoppEnvs } from "./request";
export type CollectionRunnerParam = {
collections: HoppCollection[];
envs: HoppEnvs;
delay?: number;
iterationData?: IterationDataItem[][];
iterationCount?: number;
};
export type HoppCollectionFileExt = "json";
// Indicates the shape each iteration data entry gets transformed into
export type IterationDataItem = Extract<HoppEnvPair, { value: string }>;

View File

@@ -4,6 +4,8 @@ export type TestCmdOptions = {
token?: string;
server?: string;
reporterJunit?: string;
iterationCount?: number;
iterationData?: string;
};
// Consumed in the collection `file_path_or_id` argument action handler

View File

@@ -26,6 +26,7 @@ type HoppErrors = {
MALFORMED_ENV_FILE: HoppErrorPath & HoppErrorData;
BULK_ENV_FILE: HoppErrorPath & HoppErrorData;
INVALID_FILE_TYPE: HoppErrorData;
INVALID_DATA_FILE_TYPE: HoppErrorData;
TOKEN_EXPIRED: HoppErrorData;
TOKEN_INVALID: HoppErrorData;
INVALID_ID: HoppErrorData;

View File

@@ -18,7 +18,7 @@ export type HoppEnvs = {
selected: HoppEnvPair[];
};
export type CollectionStack = {
export type CollectionQueue = {
path: string;
collection: HoppCollection;
};

View File

@@ -7,7 +7,7 @@ import { round } from "lodash-es";
import { CollectionRunnerParam } from "../types/collections";
import {
CollectionStack,
CollectionQueue,
HoppEnvs,
ProcessRequestParams,
RequestReport,
@@ -35,7 +35,7 @@ import {
} from "./request";
import { getTestMetrics } from "./test";
const { WARN, FAIL } = exceptionColors;
const { WARN, FAIL, INFO } = exceptionColors;
/**
* Processes each requests within collections to prints details of subsequent requests,
@@ -43,93 +43,134 @@ const { WARN, FAIL } = exceptionColors;
* @param param Data of hopp-collection with hopp-requests, envs to be processed.
* @returns List of report for each processed request.
*/
export const collectionsRunner = async (
param: CollectionRunnerParam
): Promise<RequestReport[]> => {
const envs: HoppEnvs = param.envs;
const delay = param.delay ?? 0;
const { collections, envs, delay, iterationCount, iterationData } = param;
const resolvedDelay = delay ?? 0;
const requestsReport: RequestReport[] = [];
const collectionStack: CollectionStack[] = getCollectionStack(
param.collections
);
const collectionQueue = getCollectionQueue(collections);
while (collectionStack.length) {
// Pop out top-most collection from stack to be processed.
const { collection, path } = <CollectionStack>collectionStack.pop();
// If iteration count is not supplied, it should be based on the size of iteration data if in scope
const resolvedIterationCount = iterationCount ?? iterationData?.length ?? 1;
// Processing each request in collection
for (const request of collection.requests) {
const _request = preProcessRequest(
request as HoppRESTRequest,
collection
);
const requestPath = `${path}/${_request.name}`;
const processRequestParams: ProcessRequestParams = {
path: requestPath,
request: _request,
envs,
delay,
};
const originalSelectedEnvs = [...envs.selected];
// Request processing initiated message.
log(WARN(`\nRunning: ${chalk.bold(requestPath)}`));
// Processing current request.
const result = await processRequest(processRequestParams)();
// Updating global & selected envs with new envs from processed-request output.
const { global, selected } = result.envs;
envs.global = global;
envs.selected = selected;
// Storing current request's report.
const requestReport = result.report;
requestsReport.push(requestReport);
for (let count = 0; count < resolvedIterationCount; count++) {
if (resolvedIterationCount > 1) {
log(INFO(`\nIteration: ${count + 1}/${resolvedIterationCount}`));
}
// Pushing remaining folders realted collection to stack.
for (const folder of collection.folders) {
const updatedFolder: HoppCollection = { ...folder };
// Reset `envs` to the original value at the start of each iteration
envs.selected = [...originalSelectedEnvs];
if (updatedFolder.auth?.authType === "inherit") {
updatedFolder.auth = collection.auth;
}
if (iterationData) {
// Ensure last item is picked if the iteration count exceeds size of the iteration data
const iterationDataItem =
iterationData[Math.min(count, iterationData.length - 1)];
if (collection.headers?.length) {
// Filter out header entries present in the parent collection under the same name
// This ensures the folder headers take precedence over the collection headers
const filteredHeaders = collection.headers.filter(
(collectionHeaderEntries) => {
return !updatedFolder.headers.some(
(folderHeaderEntries) =>
folderHeaderEntries.key === collectionHeaderEntries.key
);
}
);
updatedFolder.headers.push(...filteredHeaders);
}
// Ensure iteration data takes priority over supplied environment variables
envs.selected = envs.selected
.filter(
(envPair) =>
!iterationDataItem.some((dataPair) => dataPair.key === envPair.key)
)
.concat(iterationDataItem);
}
collectionStack.push({
path: `${path}/${updatedFolder.name}`,
collection: updatedFolder,
});
for (const { collection, path } of collectionQueue) {
await processCollection(
collection,
path,
envs,
resolvedDelay,
requestsReport
);
}
}
return requestsReport;
};
const processCollection = async (
collection: HoppCollection,
path: string,
envs: HoppEnvs,
delay: number,
requestsReport: RequestReport[]
) => {
// Process each request in the collection
for (const request of collection.requests) {
const _request = preProcessRequest(request as HoppRESTRequest, collection);
const requestPath = `${path}/${_request.name}`;
const processRequestParams: ProcessRequestParams = {
path: requestPath,
request: _request,
envs,
delay,
};
// Request processing initiated message.
log(WARN(`\nRunning: ${chalk.bold(requestPath)}`));
// Processing current request.
const result = await processRequest(processRequestParams)();
// Updating global & selected envs with new envs from processed-request output.
const { global, selected } = result.envs;
envs.global = global;
envs.selected = selected;
// Storing current request's report.
const requestReport = result.report;
requestsReport.push(requestReport);
}
// Process each folder in the collection
for (const folder of collection.folders) {
const updatedFolder: HoppCollection = { ...folder };
if (updatedFolder.auth?.authType === "inherit") {
updatedFolder.auth = collection.auth;
}
if (collection.headers?.length) {
// Filter out header entries present in the parent collection under the same name
// This ensures the folder headers take precedence over the collection headers
const filteredHeaders = collection.headers.filter(
(collectionHeaderEntries) => {
return !updatedFolder.headers.some(
(folderHeaderEntries) =>
folderHeaderEntries.key === collectionHeaderEntries.key
);
}
);
updatedFolder.headers.push(...filteredHeaders);
}
await processCollection(
updatedFolder,
`${path}/${updatedFolder.name}`,
envs,
delay,
requestsReport
);
}
};
/**
* Transforms collections to generate collection-stack which describes each collection's
* path within collection & the collection itself.
* @param collections Hopp-collection objects to be mapped to collection-stack type.
* @returns Mapped collections to collection-stack.
*/
const getCollectionStack = (collections: HoppCollection[]): CollectionStack[] =>
const getCollectionQueue = (collections: HoppCollection[]): CollectionQueue[] =>
pipe(
collections,
A.map(
(collection) => <CollectionStack>{ collection, path: collection.name }
(collection) => <CollectionQueue>{ collection, path: collection.name }
)
);