{"id":15881500,"url":"https://github.com/khalid050/seaotter","last_synced_at":"2026-05-07T13:46:04.922Z","repository":{"id":209380415,"uuid":"723902291","full_name":"khalid050/Seaotter","owner":"khalid050","description":"Sea Otter is a testing framework :)","archived":false,"fork":false,"pushed_at":"2023-12-04T03:33:35.000Z","size":164,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T05:46:36.679Z","etag":null,"topics":["javascript","testing","typescript","vscode","vscode-extension"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khalid050.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-11-27T02:01:56.000Z","updated_at":"2023-12-04T03:33:38.000Z","dependencies_parsed_at":"2023-12-14T23:11:51.000Z","dependency_job_id":"2822cd15-31c2-4d0c-85e7-705dc7002e01","html_url":"https://github.com/khalid050/Seaotter","commit_stats":{"total_commits":13,"total_committers":1,"mean_commits":13.0,"dds":0.0,"last_synced_commit":"cf08f440af98324460acb8788c87d22d5f5f7b89"},"previous_names":["khalid050/seaotter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/khalid050/Seaotter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalid050%2FSeaotter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalid050%2FSeaotter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalid050%2FSeaotter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalid050%2FSeaotter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khalid050","download_url":"https://codeload.github.com/khalid050/Seaotter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalid050%2FSeaotter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262188397,"owners_count":23272341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","testing","typescript","vscode","vscode-extension"],"created_at":"2024-10-06T03:41:59.419Z","updated_at":"2026-05-07T13:46:04.876Z","avatar_url":"https://github.com/khalid050.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003eSea Otter\u003c/h1\u003e\n\n[![Project Status: Pre-Alpha](https://img.shields.io/badge/Project%20Status-Pre--Alpha-red.svg)](https://shields.io/#your-badge)\n[![npm version](https://badge.fury.io/js/seaotter.svg)](https://badge.fury.io/js/seaotter)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n\u003ch2\u003e Getting started\u003c/h2\u003e\n🌊 Dive into testing with SeaOtter\n\u003cp\u003e\n\n\u003ch2\u003eStep 1: Create a configuration object with details about your test environment. Here's an example:\n\u003c/h2\u003e\n\n1) `npm i -D seaotter`\n2) Get the accompanying vscode extension for a superior experience (not yet published)\n\n```javascript\nconst config = {\n  testDirectory: \"/Absolute/Path/To/Test/Directory\",\n  fastFail: true,\n  random: false,\n  tests: [\"asyncTest.js\"],\n};\n```\n\nAdjust the testDirectory to the absolute path of your test directory. Specify the tests you want to run in the tests array. Set fastFail to true for quicker test termination on the first failure, and toggle random to shuffle test execution order.\n\n\u003ch2\u003eStep 2: Write a test\u003c/h2\u003e\n\n```javascript\notter.explore`Create new User ${ MyTag }`(() =\u003e {\n  otter.test`Login with valid credentials`(async () =\u003e {\n    await simulateLogin(\"validUsername\", \"validPassword\");\n    await verifyOnHomePage();\n  });\n\n  test`Login with invalid credentials`(async () =\u003e {\n    await simulateLogin(\n      \"invalidUsername\",\n      \"invalidPassword\"\n    );\n\n  const a = 10;\n  const b = 20;\n  const c = 5;\n  \n  expect`${a} toEqual ${a}`;\n  expect`${a} toBeGreaterThan ${b}`;\n  expect`${c} toBeLessThan ${a}`;\n});\n```\n\n\u003ch2\u003eStep 3: Run your tests \u003c/h1\u003e\n\n```javascript\nimport { otter } from \"seaotter\";\nimport config from \"./config\";\n\notter.wadeIn(config);\n\n(async function () {\n  await otter.dive();\n})();\n```\n\nThis method offers a straightforward way to run your tests.\n\n\u003ch3\u003eCustom Test Execution using Generator (Alternative Approach)\u003c/h3\u003e\n\nIf you prefer more control over the test execution process, you can have the otter cruise through a generator.\nThis approach allows you to perform additional processing after each test and before the next one begins.\nThe generator provides valuable metadata about each test so that you can customize your workflow!\n\n```javascript\n(async function () {\n  for await (const test of otter.cruise()) {\n    // do something with metadata\n  }\n})();\n\n```\nIf running the former way, and running tests in quiet mode you can listen for the failure events\n\n```javascript\n   otter.on('testFailure', (error) =\u003e {\n     doSomething(error)\n   });\n```\n\n\n\u003ch2\u003eUsing the CLI\u003c/h2\u003e\nYou'll need to setup some env variables\n\n```bash\nnpm i -g seaotter\n```\n\n```bash\nexport TEST_DIR=\"/absolute/path/to/test/dir\"\n\n# This is where your dive/cruise methods are used\nexport TEST_ENTRY=\"/absolute/path/to/entry\"\n\notter \u003ctest(s)\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhalid050%2Fseaotter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhalid050%2Fseaotter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhalid050%2Fseaotter/lists"}