{"id":15102660,"url":"https://github.com/jeffnyman/playwright-eschaton","last_synced_at":"2026-02-16T17:34:00.441Z","repository":{"id":252550939,"uuid":"840766778","full_name":"jeffnyman/playwright-eschaton","owner":"jeffnyman","description":"A Pedagogical Pastiche of Playwright","archived":false,"fork":false,"pushed_at":"2024-08-22T15:46:12.000Z","size":160,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-04T00:49:15.529Z","etag":null,"topics":["cucumber-js","playwright","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffnyman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/@types/env.d.ts","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-10T16:10:49.000Z","updated_at":"2024-08-22T15:46:15.000Z","dependencies_parsed_at":"2024-10-31T03:35:17.930Z","dependency_job_id":null,"html_url":"https://github.com/jeffnyman/playwright-eschaton","commit_stats":{"total_commits":22,"total_committers":1,"mean_commits":22.0,"dds":0.0,"last_synced_commit":"bd1edb86d66a24de47fc0de10278dee26c24a3a6"},"previous_names":["jeffnyman/playwright-eschaton"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jeffnyman/playwright-eschaton","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffnyman%2Fplaywright-eschaton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffnyman%2Fplaywright-eschaton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffnyman%2Fplaywright-eschaton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffnyman%2Fplaywright-eschaton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffnyman","download_url":"https://codeload.github.com/jeffnyman/playwright-eschaton/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffnyman%2Fplaywright-eschaton/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29513991,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T09:05:14.864Z","status":"ssl_error","status_checked_at":"2026-02-16T08:55:59.364Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cucumber-js","playwright","typescript"],"created_at":"2024-09-25T19:04:04.947Z","updated_at":"2026-02-16T17:34:00.419Z","avatar_url":"https://github.com/jeffnyman.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  🎭 Playwright Eschaton 🎭\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eThe stage is set, let the automation begin.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eA Pedagogical Pastiche of Playwright Programming\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jeffnyman/playwright-eschaton/actions/workflows/playwright.yml\"\u003e\u003cimg src=\"https://github.com/jeffnyman/playwright-eschaton/actions/workflows/playwright.yml/badge.svg\" alt=\"Playwright Eschaton Test Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/jeffnyman/playwright-eschaton/actions/workflows/lint.yaml\"\u003e\u003cimg src=\"https://github.com/vitalets/playwright-bdd/actions/workflows/lint.yaml/badge.svg\" alt=\"Playwright Eschaton Lint Status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jeffnyman/playwright-eschatont/blob/main/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"Playwright Eschaton is released under the MIT license.\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Works on \u003cimg src=\"assets/win_sm.png\" alt=\"Windows\"\u003e Windows,\n  \u003cimg src=\"assets/apple_sm.png\" alt=\"macOS\"\u003e macOS and\n  \u003cimg src=\"assets/linux_sm.png\" alt=\"Linux\"\u003e Linux.\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n\"Our lives now are an internship for the eschaton.\"\u003cbr\u003e\nRussell D. Moore, \u003cem\u003eOnward: Engaging the Culture without Losing the Gospel\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n## 🚀 Learning\n\n\u003e [!TIP]\n\u003e This repo is meant to be _studied_ and played around with.\n\nLook at how the various projects are set up; look at what happens when you execute them; look at some of the design decisions. Nothing in here is touted as the \"right\" way necessarily. What is here is a means to show what does work and give you a starting point for your own learning. I recommend looking at the **Execution** section below to get a feel for what's in place. You can also see **Jeff's Principles of Coding** further down for some of my overall design thinking.\n\nIf you find any of this useful, consider leaving a ⭐️ for this repo.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://playwright.dev/docs/intro\"\u003e\u003cimg src=\"https://img.shields.io/badge/Documentation-Playwright-1c8620.svg?logo=playwright\" alt=\"Playwright.dev\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/microsoft/playwright/tree/main\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-Playwright-1c8620.svg?logo=github\" alt=\"Playwright - GitHub\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://stackoverflow.com/questions/tagged/playwright\"\u003e\u003cimg src=\"https://img.shields.io/badge/stackoverflow-Playwright-e87922.svg?logo=stackoverflow\" alt=\"Playwright - Stack Overflow\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://cucumber.io/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Documentation-Cucumber-23d96c.svg?logo=Cucumber\" alt=\"Cucumber.io\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/cucumber\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-Cucumber-23d96c.svg?logo=github\" alt=\"Cucumber - GitHub\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://stackoverflow.com/questions/tagged/cucumber\"\u003e\u003cimg src=\"https://img.shields.io/badge/stackoverflow-Cucumber-e87922.svg?logo=stackoverflow\" alt=\"Cucumber - Stack Overflow\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## 🟢 Prerequisites\n\nMake sure you have [Node.js](https://nodejs.org/en). The LTS version should be fine. You will also need the `npm` package manager, which comes with Node.js. A development environment or IDE with TypeScript/JavaScript support will help. [Visual Studio Code](https://code.visualstudio.com/) is a good choice.\n\n## ⚡ Quick Start\n\nClone the repository and then set everything up:\n\n```shell\nnpm ci\n```\n\nMake sure to install the browsers that Playwright will need.\n\n```shell\nnpx playwright install\n```\n\n## 💻 Execution\n\nIn Playwright, a project is a logical group of tests that run using the same configuration. The sections below will each be shown with a command that executes the specific project. For any examples that are marked as UI, you can pass the `--headed` argument in order to see the browser execution.\n\nYou can run any Playwright tests using the [VS Code extension](https://playwright.dev/docs/getting-started-vscode). This project will recommend that extension if you are using VS Code. However, it is highly recommended that you understand how to execute from the CLI.\n\n### 🔸 Tautology Tests\n\nThese tests do not use a browser at all. They are meant to showcase the idea of simply writing tests and having some general tautologies that validate the basic operation of the testing framework.\n\nOne of the tautology tests isn't entirely frivolous since it serves as a small API test as well. My [Swagger UI](https://testerstories.com/swagger-ui) is set up with some simple OpenAPI specs, one of which is my [tautology spec](https://testerstories.com/files/api/openapi_test.yml) which is run as part of this project.\n\n```shell\nnpx playwright test --project \"Tautology Tests\"\n```\n\nTry running just the tests marked as `@canary`. You have to do this differently based on the operating system. For any POSIX-based system:\n\n```shell\nnpx playwright test --project \"Tautology Tests\" --grep @canary\n```\n\nFor Windows, particularly in Powershell:\n\n```shell\nnpx playwright test --project \"Tautology Tests\" --grep \"@canary\"\n```\n\n### 🔸 Sauce Labs Example (UI)\n\nThis is an example project that shows how [project dependencies](https://playwright.dev/docs/next/test-projects#dependencies) in Playwright work. The idea is that you can login to an application and save those logged in credentials in storage state. Tests that rely on the logged in setup can then use this storage stage when executing, which means they don't have to login again before each test.\n\nThis project also shows the use of the `.env` file to set environment variables that can be used as part of your tests. To run these tests, you'll want to create an `.env` in the project directory if you don't already have one. By design, the `.env` file is not version controlled.\n\n```shell\ncp .env.sample .env.\n```\n\nThen specify these two settings:\n\n```ini\nSAUCE_USERNAME=standard_user\nSAUCE_PASSWORD=secret_sauce\n```\n\nThe setup test will use these credentials to log in. You could actually run the setup test by itself since it's a distinct project. You would just do this:\n\n```shell\nnpx playwright test --project \"Sauce Setup\"\n```\n\nThis setup script will generate a file called `.auth/sauce_user.json`. However you don't actually have to do that! That setup project is a dependency of another project, one that executes tests against the Sauce Labs site. Those tests live in a project that calls the setup project as a dependency. To run the tests that depend on the setup project:\n\n```shell\nnpx playwright test --project \"Sauce Logged In Tests\"\n```\n\nThis project uses a `storageState` to indicate which storage state information should be used. That's stored in a constant called `SAUCE_STORAGE_STATE` and that constant points to the above mentioned `sauce_user.json` that was generated.\n\nThere's also a project that does _not_ use the setup project and that's because this other project does not require a login. To run that, you can do this:\n\n```shell\nnpx playwright test --project \"Sauce Logged Out Tests\"\n```\n\nThis would be a good example where you might have tests that run only when logged in and other tests that check happens when not logged in.\n\nThis small little project is actually showcasing a series of things, such as environment settings, the use of storage state and project dependencies that are conditionalized based on whether the storage state is needed.\n\nIn terms of the tests, you might also note that this project indicates a specific `testIdAttribute` that is used by the Sauce Labs demo, which is `data-test`. This is what will be looked for when calls are made to the `getByTestId()` function. You might also check out how the projects use `testMatch` and `testIgnore` settings based on the name of the spec files.\n\n### 🔸 Ludic UI Tests\n\nThe Ludic pages are simply designed as blog content pages. Their complexity comes in from how the header and the scroll-to-top functionality have dynamic aspects, in terms of how and when they display. The dark-light mode is a relatively simply implementation that also accounts for the system setting. There are also \"click to enlarge\" elements on the page that provide a modal view for images.\n\nTo run these tests:\n\n```shell\nnpx playwright test --project \"Ludic UI Tests\"\n```\n\n### 🔸 Playground UI Tests\n\nThe playground area is designed to provide a simple landing page but then add some complexity. For example, the navigation pull out menu can have some challenges around checking for visibility and whether the widgets are in the viewport or not.\n\nTo run all the tests:\n\n```shell\nnpx playwright test --project \"Playground UI Tests\"\n```\n\nThe various pages within the playground are meant to run the gamut from relatively simple implementations of forms to slightly complex tables to elements that dynamically update but only upon the detection of certain user actions.\n\nThe planet weight area has two tests: one that uses a page object and one that does not. The same applies to the landing page tests. In both of those areas, you can see examples of iterating over data conditions while providing a single test condition.\n\n### 🔸 Todo MVC UI Tests\n\nI have provided my own [Todo MVC](https://testerstories.com/todomvc) application. You can run the tests:\n\n```shell\nnpx playwright test --project \"Todo UI Tests\"\n```\n\nThe Page Object Model is the often recommended approach for effective code organization in tests. Yet the very naming of the model -- page object -- tends to have people modeling only a whole page. Yet, there are often sections of a page that make sense to model on their own.\n\nSome of these might be common elements between all pages, such as any navigation, headers and footers. Others might simply be defined areas of use that make sense to model distinctly. We can call this a Component Model approach.\n\nA component approach would provide a bit more possibility for reuse but also for composability. The basic idea would be to create an intermediate layer of components that model aspects of the application and that all tests can utilie.\n\nIn this project, the components for the Todo MVC application can be found in the `components` folder for the project. The `ts-todo-app.spec.ts` shows the tests using my TesterStories application but using the component model.\n\nThe `demo-todo-app.spec.ts` file is the same file that comes with Playwright as a working example. What I've done is show that this test, without modification, works on my slightly modified Todo MVC example. What this does is allow you to see the component approach side-by-side with the non-component approach.\n\n### 🔸 Weather (API)\n\nTo run the tests for this you need to obtain an account and API key from Weather API. You can see the OpenAPI spec I have available for the [OpenWeatherMap API](https://testerstories.com/swagger-ui/?urls.primaryName=Weather+API), which I'm using for this example.\n\nThis project, like the Sauce Labs example, shows the use of the `.env` file to set environment variables that can be used as part of your tests. To run these tests, you'll want to create an `.env` in the project directory if you don't already have one. By design, the `.env` file is not version controlled.\n\n```shell\ncp .env.sample .env.\n```\n\nThen specify these two settings:\n\n```ini\nWEATHER_API_KEY=YOUR API KEY GOES HERE\nWEATHER_API_URL=https://api.weatherapi.com/v1\n```\n\nYou need to place your personal API key as the value for `WEATHER_API_KEY`. Once you have that in place, you can run the Playwright specific tests for this project:\n\n```shell\nnpx playwright test --project=\"Weather API Tests\"\n```\n\nOne thing to note about these Playwright tests is how they are using the `APIRequestContext`. This is used to provide an abstraction layer for the API tests, which can be seen in `tests/api/weather/activity/invoke.ts`.\n\nYou can also run the Playwright tests via the following command:\n\n```shell\nnpm run test:weather:pw\n```\n\nThe reason for the alternate execution method is because part of the goal of this particular set of tests it to also show how to leverage multiple tools. For example, I have some Newman tests for this as well. These tests are based on Postman collection files. You can run these with:\n\n```shell\nnpm run test:weather:postman\n```\n\nThere is also a supplemental project that runs the exact same API tests as the Playwright example but using Jest alone. You can run that with:\n\n```shell\nnpm run test:weather:jest\n```\n\nWhat all of these examples show is that you can run multiple test styles within the same project.\n\n### 🔸 Booker API Tests\n\nThe goal of this project is to demonstrate how to create an abstraction layer on top of standard testing practices, specifically focusing on API interactions using Playwright. To run the tests:\n\n```shell\nnpx playwright test --project=\"Booker API Tests\"\n```\n\nBy building the abstraction, I've effectively created a test harness that wraps Playwright's internal operations, allowing for more streamlined and reusable test code. Here the abstraction is placed in the `harness` directory of the Booker project although this would likely be put in a more central location for any API tests.\n\n#### API Abstraction in `api.ts`\n\nThe `harness/api.ts` file encapsulates all the logic for making API requests within your tests. It defines a class named API, which acts as a dedicated client for interacting with the API. By abstracting API communication into this class, we separate concerns and provide a clean interface for the rest of the test suite.\n\nThe API class is initialized with an `APIRequestContext`, a Playwright object that manages HTTP requests. The core method, `generateRequest`, handles the complexity of sending HTTP requests. This method dynamically constructs requests based on parameters such as the HTTP method, endpoint, request body, and authentication token, and returns the resulting response. Helper methods like `getRequest`, `postRequest`, and others are built on top of generateRequest, simplifying the process of making common API calls in your tests. This setup abstracts away the underlying details of API communication, allowing tests to focus on validation logic rather than request construction.\n\n#### Fixture Setup in `fixture.ts`\n\nThe `harness/fixture.ts` file defines a fixture that integrates the API class into the Playwright test environment. This fixture sets up the API instance and makes it available to all tests via Playwright’s dependency injection mechanism.\n\nThe fixture is built using Playwright’s extend function, which allows you to augment the base test environment with custom fixtures. In this case, the API fixture is created to inject an instance of the API class, initialized with the Playwright request context, into the test environment. This ensures that every test block has access to the same, consistent API client, facilitating more uniform and reliable tests.\n\nAdditionally, the fixture file defines TypeScript interfaces like `AuthResponse` and `BookingResponse` to describe the expected structure of API responses. These interfaces not only provide type safety but also serve as documentation, clearly defining what the tests expect from the API.\n\n#### Test Implementation in `booker.spec.ts`\n\nThe test suite in `booker.spec.ts` showcases how to use the API abstraction and fixture to write clean, maintainable tests. The test blocks leverage the API parameter, injected by the fixture, to interact with the API. This allows the tests to focus purely on the validation of API behavior, without worrying about the intricacies of request handling.\n\nEach test case follows a straightforward structure: making an API call using the appropriate method from the `API` class and then asserting the response using Playwright’s assertion library. Notably, the tests make use of [soft assertions](https://playwright.dev/docs/test-assertions#soft-assertions) provided by Playwright, which allow the test execution to continue even if an assertion fails. This is particularly useful in scenarios where you want to validate multiple aspects of a response without halting the test prematurely.\n\n#### Overall Structure\n\nBy structuring the Booker API project this way, what's achieved is a clear separation of concerns: the API class handles the communication logic, the fixture integrates this logic into the test environment, and the test files focus on validation. This design promotes reusability, maintainability, and clarity in API testing.\n\n## 📊 Reporting\n\nThis project generates all of the standard reporting possible for tests in a Playwright context. You can always view the Playwright generated report with:\n\n```shell\nnpm run report:pw\n```\n\nIt's also possible to write custom reporters and one is provided with this project.\n\n### Summary Reporter\n\nThis is a custom reporter is provided that generates a very condensed view of test execution. This condensed format could be used to publish test results to something like an SMS message or a Slack channel update. The default output location is to the root project directory as a file called `summary.txt`. You can change this location in the reporter configuration, which this project does.\n\nThere is a `Stats` interface provided that the custom summary reporter uses but this can also be used by your own custom reporter, essentially based on the summary report. For an example of how to do that, you'll see a file called `concise.ts` in the `support/reporter` directory. This project uses that concise report as part of the reporter configuration.\n\n## 🥒 Cucumber\n\nThis repo shows the usage of Playwright in a Cucumber context. To that end, the repo provides some settings that try to configure Visual Studio Code for you. These are provided in the `.vscode` folder that will activate if you are using that editor. This should hook up the feature files and the step definitions so that the editor is aware of both and how they are connected.\n\nTo run a dry run of the specifications:\n\n```shell\nnpm run specs:dryrun\n```\n\nTo run the specs:\n\n```shell\nnpm run specs\n```\n\nIf you want to look at the Cucumber report:\n\n```shell\nnpm run specs:report\n```\n\nIf you want to generate and show the dashboard report:\n\n```shell\nnpm run specs:dashboard\nnpm run specs:dashboard:show\n```\n\nThis repo is set up to have Cucumber generate a \"rerun\" file for tests that failed. You can run that execution profile like this:\n\n```shell\nnpm run specs:rerun\n```\n\nObviously for that work you would need some failing tests.\n\nFinally, Cucumber.js doesn't easily allow simple execution of one feature file from the command line. It does allow you to pass a regular expression which will check all scenarios for the identifier you provide. Some examples:\n\n```shell\nnpx cucumber-js test --name \"Weight on Mercury\"\nnpx cucumber-js test --name \"Mercury\"\n```\n\n## 🧬 Code Quality\n\nThis project uses Prettier.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://prettier.io/docs/en/index.html\"\u003e\u003cimg src=\"https://img.shields.io/badge/Documentation-Prettier-f7ba3e.svg?logo=prettier\" alt=\"Prettier\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/prettier/prettier\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-Prettier-f7ba3e.svg?logo=github\" alt=\"Prettier - GitHub\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://stackoverflow.com/questions/tagged/prettier\"\u003e\u003cimg src=\"https://img.shields.io/badge/stackoverflow-Prettier-e87922.svg?logo=stackoverflow\" alt=\"Prettier - Stack Overflow\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nThis is critical for any automation-based project. To run Prettier and automatically fix any issues, you can do this:\n\n```shell\nnpm run format:fix\n```\n\nThis project uses ESLint.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://eslint.org/docs/latest/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Documentation-ESLint-4b32c3.svg?logo=eslint\" alt=\"ESLint\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/eslint/eslint\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-ESLint-4b32c3.svg?logo=github\" alt=\"ESLint - GitHub\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://stackoverflow.com/questions/tagged/eslint\"\u003e\u003cimg src=\"https://img.shields.io/badge/stackoverflow-ESLint-e87922.svg?logo=stackoverflow\" alt=\"ESLint - Stack Overflow\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nYou can run linting in this project by doing this:\n\n```shell\nnpm run lint\n```\n\nIf you're feeling confident that the linter will be able to auto-fix your isue, you can run it like this:\n\n```shell\nnpm run lint:fix\n```\n\n## 🌀 Pipeline\n\nThis project is using GitHub Actions. Check [playwright.yml](https://github.com/jeffnyman/playwright-eschaton/blob/main/.github/workflows/playwright.yml).\n\n## 🐳 Docker\n\nTo run tests in Docker containers, follow these steps:\n\n1. **Build the Docker Image**\n\nInstall Docker and then build the Docker image from the provided Dockerfile:\n\n```shell\ndocker build -t \u003cimage-name\u003e .\n```\n\n2. **Create and Launch the Container**\n\nCreate a container from the image and launch it in detached mode:\n\n```shell\ndocker run -it -d \u003cimage-name\u003e\n```\n\n3. **Verify Container is Running**\n\nCheck that the container is up and running by listing all containers:\n\n```shell\ndocker ps -a\n```\n\nCopy the `container-id` of your running container.\n\n4. **Log into the Container**\n\nLog into the running container's shell:\n\n```shell\ndocker exec -it \u003ccontainer-id\u003e bash\n```\n\n5. **Run Playwright Tests**\n\nInside the Docker container, run your Playwright tests as usual:\n\n```shell\nnpx playwright test\n```\n\n6. **Stop and Remove the Container (optional)**\n\nAfter your tests are done, you can stop and remove the container to clean up:\n\n```shell\ndocker stop \u003ccontainer-id\u003e\ndocker rm \u003ccontainer-id\u003e\n```\n\n### Example Commands\n\nBuild the Docker image:\n\n```shell\ndocker build -t playwright-eschaton .\n```\n\nCreate and run the container:\n\n```shell\ndocker run -it -d playwright-eschaton\n```\n\nLog into the container:\n\n```shell\ndocker exec -it \u003ccontainer-id\u003e bash\n```\n\nRun tests inside the container:\n\n```shell\nnpx playwright test\n```\n\n## 🔸 Test References\n\nI'm using my own site material for this. One is a sample article called [A Ludic Historian Précis](https://testerstories.com/xyzzy/ludic/article/precis.html). The other is my [Playwright Playground](https://testerstories.com/xyzzy/).\n\n## 👨‍💻 Jeff's Principles of Coding\n\n- Embrace small code.\n- Abstraction encourages clarity.\n- No computation is too small to be put into a helper function.\n- No expression is too simple to be given a name.\n- Small code is more easily seen to be obviously correct.\n- Code that’s more obviously correct can be more easily composed.\n- Be willing to trade elegance of design for practicality of implementation.\n- Embrace brevity, but do not sacrifice readability. Concise, not terse.\n- Prefer elegance over efficiency where efficiency is less than critical.\n\n## 📜 Why \"Playwright Eschaton\"?\n\nAs an existential note, this project is not intended to [immanentize the eschaton](https://en.wikipedia.org/wiki/Immanentize_the_eschaton). (Just in case anyone was worried.)\n\nThe _eschaton_ is from the ancient Greek term _ἔσχατον_ (_éskhaton_). The word literally refers to the 'last thing' or even 'the end.' When construed as the latter, the phrase tends to refer to the final events, or last days, of history. In theological circles it also refers to the ultimate destiny of the human race.\n\nA fairly grandiose set of meanings, to say the least. All my current project does, however, is indicate what I believe to be the 'last thing' I intend to put up regarding my experiments with development and automation around [Playwright](https://playwright.dev).\n\n---\n\n\u003cp align=\"center\"\u003e\n\"I am the Eschaton. I am not your God.\u003cbr\u003e\nI am descended from you, and exist in your future.\u003cbr\u003e\nThou shalt not violate causality within my historic light cone.\u003cbr\u003e\nOr else.\"\u003cbr\u003e\u003cbr\u003e\nCharles Stross, \u003cem\u003eSingularity Sky\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n## ⚖ License\n\nThe code used in this project is licensed under the [MIT license](https://github.com/jeffnyman/playwright-eschaton/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffnyman%2Fplaywright-eschaton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffnyman%2Fplaywright-eschaton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffnyman%2Fplaywright-eschaton/lists"}