{"id":16689224,"url":"https://github.com/sskorol/aqa-playground","last_synced_at":"2025-07-13T23:07:47.574Z","repository":{"id":197259159,"uuid":"698281267","full_name":"sskorol/aqa-playground","owner":"sskorol","description":"Comprehensive testbed designed primarily for passionate SDETs to practice their skills in real-world scenarios","archived":false,"fork":false,"pushed_at":"2023-10-12T21:40:26.000Z","size":759,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-15T10:39:08.444Z","etag":null,"topics":["aqa","automated-testing","automation","docker","nestjs","playground","react","stripe","testing","vite"],"latest_commit_sha":null,"homepage":"https://your.aqa-playground.pro/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sskorol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-29T15:01:07.000Z","updated_at":"2024-04-09T20:32:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"504ddb5e-e133-4a42-bafc-cd4fab914ff4","html_url":"https://github.com/sskorol/aqa-playground","commit_stats":null,"previous_names":["sskorol/aqa-playground"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sskorol/aqa-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskorol%2Faqa-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskorol%2Faqa-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskorol%2Faqa-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskorol%2Faqa-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sskorol","download_url":"https://codeload.github.com/sskorol/aqa-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskorol%2Faqa-playground/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265218738,"owners_count":23729527,"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":["aqa","automated-testing","automation","docker","nestjs","playground","react","stripe","testing","vite"],"created_at":"2024-10-12T15:47:33.123Z","updated_at":"2025-07-13T23:07:47.520Z","avatar_url":"https://github.com/sskorol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## AQA Playground\n\n:mortar_board: The AQA Playground is a comprehensive testbed designed primarily for passionate SDETs to practice their skills in real-world scenarios.\n\n:fire: Integrating PostgreSQL, NestJS / Swagger / JWT Auth, React, Docker, and Stripe, this project simulates a full-fledged application ecosystem, providing hands-on experience for frontend and backend testing activities. \n\n\u003cvideo src=\"https://github.com/sskorol/aqa-playground/assets/6638780/887f3b92-4558-4ffe-a35b-127037bfb73a\"\u003e\u003c/video\u003e\n\n### Table of Contents\n1. [Installation](#installation)\n    - [NodeJS](#nodejs)\n    - [Docker](#docker)\n    - [Stripe Payments](#stripe-payments)\n    - [Source Code](#source-code)\n    - [Environment Variables](#environment-variables)\n      - [Frontend Config](#frontend-config)\n      - [Backend Config](#backend-config)\n    - [Database](#database)\n2. [Docker](#docker-1)\n    - [Partial mode](#partial-mode)\n    - [Full deployment](#full-deployment)\n3. [Running](#running)\n    - [Dev Mode](#dev-mode)\n    - [Prod Mode](#prod-mode)\n    - [Operating](#operating)\n4. [API](#api)\n5. [Tests](#tests)\n6. [Credits](#credits)\n7. [ToDo or Dreams](#todo-or-dreams)\n\n### Installation\n\nUse the following instructions to set everything up on your local machine.\n\n#### NodeJS\n\nEnsure [node-16](https://nodejs.org/en/blog/release/v16.20.2) and npm 8+ are installed:\n```shell\nnode --version  # v16.20.2\nnpm --version   # 8.19.4\n```\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Docker\n\nYou have to have Docker to be able to deploy either only DB services or the entire app in containers.\nFollow the official guide to install:\n- [Docker](https://docs.docker.com/engine/install/)\n- [Compose](https://docs.docker.com/compose/install/)\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Stripe Payments\n\n- Sign up to [Stripe](https://dashboard.stripe.com/register) to access their API.\n- **Important**: don't activate live payments! Testing mode is enabled by default. Just leave it as is. \n- Go to **Developers** tab -\u003e API keys -\u003e copy **Publishable** and **Secret** keys. The former is required for frontend; the latter is for backend.\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Source Code\n\nClone sources:\n```shell\ngit clone https://github.com/sskorol/aqa-playground.git \u0026\u0026 cd aqa-playground\n```\n\nInstall dependencies:\n```shell\nnpm ci\n```\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Environment Variables\n\nThe recommended way of setting up sensitive data for development is using your IDE's run/debug configuration profiles.\nHowever, for production builds, you'll likely use CLI or Docker.\nThat's where you need to adjust `.env.production` file for such scenarios (see [Environment Variables](#environment-variables)).\nBelow you'll find sample values that could be also used in IDE.\n\n[**Go top**](#table-of-contents) :point_up:\n\n##### Backend Config\n\n```shell\ncd packages/backend \u0026\u0026 nano .env.production\n```\n\n```shell\n# .env.production\n\n# Postgres\nPOSTGRES_USER=admin\nPOSTGRES_PASSWORD=admin\nPOSTGRES_DB=aqa\n# PG Admin\nPGADMIN_DEFAULT_EMAIL=admin@email.com\nPGADMIN_DEFAULT_PASSWORD=admin\n# BE\nDB_HOST=postgres\nDB_LOGGING=true\nDB_NAME=aqa\nDB_PASSWORD=admin\nDB_PORT=5432\nDB_SYNC=true\nDB_USERNAME=admin\nJWT_SECRET=aqasecret\nPORT=9090\nCORS_WHITELIST=http://localhost:3000\nSTRIPE_API_SECRET_KEY=YOUR_SECRET_STRIPE_KEY\n```\n\nHere, you can use any values. Just a small note regarding PGAdmin and Postgres communication.\nPGAdmin provides a GUI to manage Postgres instances in Docker. But as you'd access it from the host OS,\nit's quite easy to get confused with connection settings. Just always keep in mind that when you run services in Docker\nand expect them to communicate with each other, the actual connection request will always be made from within Docker network.\nSo despite you running GUI on the host from your web browser and exposing external docker ports,\nyou should still provide the **name** of the docker service `postgres` and its **internal** port `5432` to establish a connection.\nThat differs from the direct DB access from the host, where you have to use an **external** port specified in docker-compose config.\n\nAlso, note about dependencies: if you change ports or service names, don't forget to update the relevant info within FE/BE env vars\nand Vite/Nginx configs (currently, they use a hardcoded BE URL).\n\nRegarding Stripe integration: just don't mix up the keys. The secret is always on the BE, publishable key is on FE-side.\n\n[**Go top**](#table-of-contents) :point_up:\n\n##### Frontend Config\n\n```shell\ncd packages/frontend \u0026\u0026 nano .env.production\n```\n\n```shell\nVITE_REACT_APP_BE_URL=/api\nVITE_REACT_APP_STRIPE_PUB_KEY=YOUR_PUBLISHABLE_STRIPE_KEY\n```\n\nNote that frontend uses [Vite](https://vitejs.dev/), allowing you to spawn the dev server in milliseconds.\nBut we have to pay for it by following their conventions. Specifically, env vars must have `VITE_` prefix.\nMoreover, you can't use `process.env.VAR_NAME` in the code. Vite uses [import-meta-env](https://iendeavor.github.io/import-meta-env/guide/getting-started/introduction.html)\nwhich forces us to switch to `import.meta.env.VAR_NAME` syntax.\n\nIt's also worth mentioning that `VITE_REACT_APP_BE_URL` value is different for dev and prod modes.\nIn dev mode, you have to provide a full BE URL like `http://localhost:9090`. In prod mode, as we produce static assets,\na reverse proxy is used on Nginx-level. It maps the BE URL in Docker to `/api`. So env variable should refer to a short path instead.\n\nTo be able to inject env vars dynamically into production build while spawning Docker container,\nthere was a special hack used:\n```ts\nfunction getEnvVar(key: string): string {\n  if (window._env_ \u0026\u0026 window._env_[key]) {\n    return window._env_[key];\n  } else if (import.meta.env[key]) {\n    return import.meta.env[key];\n  }\n  throw new Error(`Environment variable ${key} is not set`);\n}\n```\n\nHere we read env vars from the `window` object while running in Docker, or via `import.meta` while local deployment.\nThe actual trick is applied in the `Dockerfile`:\n```dockerfile\nCMD [\"/bin/sh\", \"-c\", \"echo \\\"window._env_ = { VITE_REACT_APP_BE_URL: '$VITE_REACT_APP_BE_URL', VITE_REACT_APP_STRIPE_PUB_KEY: '$VITE_REACT_APP_STRIPE_PUB_KEY' }\\\" \u003e /usr/share/nginx/html/config.js \u0026\u0026 exec nginx -g 'daemon off;'\"]\n```\n\nHere we dynamically generate `config.js` with injected (during Docker container startup) env vars.\nAnd then copy it into nginx folder with static assets. `index.html` loads this script during the app startup:\n```html\n\u003cscript src=\"/config.js\"\u003e\u003c/script\u003e\n```\nSo that we can further access them in code via `getEnvVar` function.\n\nAs this config is generated only in Docker, you may still want to mock it within `public` folder to avoid errors regarding missing files. \n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Database\n\nDB is persisted locally via Docker volumes. So when you start the images listed in docker-compose configs (see [Partial Mode](#partial-mode)),\nyou'll see a new `./data` folder within backend root.\n\n[**Go top**](#table-of-contents) :point_up:\n\n### Docker\n\nThere are 2 options:\n- run the app in the dev mode but Postgres and PGAdmin in Docker\n- run the entire app in prod mode in Docker\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Partial Mode\n\nThe former option simplifies DB configuration stuff but still requires the initial setup to be done for spawning the dev environment on your host OS.\nRun the following command when your environment variables are ready:\n```shell\ndocker compose -f docker-compose.dev.yml up -d\n```\n\nIt deploys Postgres with PGAdmin, so you can connect to the database from within BE or GUI.\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Full Deployment\n\nTo run the entire stack in Docker, you have to build FE and BE first:\n```shell\ndocker compose -f docker-compose.prod.yml build\n```\n\nThen you can run it the following way:\n```shell\ndocker compose -f docker-compose.prod.yml up -d\n```\n\n[**Go top**](#table-of-contents) :point_up:\n\n### Running\n\nDepending on the previous choice, you'd run DB in Docker, and BE/FE in IDE, or everything in Docker.\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Dev Mode\n\nFirst, ensure you've set everything up, created IDE run/debug configurations with env vars, and started DB containers.\nNote that as it's a multi-module project, you must select a valid `package.json` depending on the submodule you want to deploy.\nAlso, in case of multiple NodeJS versions, ensure you've selected 16. This project hasn't been tested in the other versions. \n\nTo deploy the backend locally in the watch mode, use `start:dev` script. A similar script should be used on the frontend-side.\n\nWhen you start the backend, it connects to the DB and creates the required tables based on the entities defined in the code.\nNote that there's a `SYNCHRONIZE` flag (env var) set to `true`, which always re-creates the schema in case of any changes.\nIt's not recommended to activate it on prod, but as it's a test app, this flag gives only benefits.\n\nAt this point, you should be able to run FE and BE locally with DB in Docker.\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Prod Mode\n\nTo deploy everything in containers, just run the following command:\n```shell\ndocker compose -f docker-compose.prod.yml up -d\n```\n\n[**Go top**](#table-of-contents) :point_up:\n\n#### Operating\n\n- Open web-browser on http://localhost:3000/.\n- Create a new user via the sign-up form.\n- Open Swagger interface http://localhost:9090/api and try `/auth/login` endpoint with the newly created user.\n- Copy the `accessToken` value returned in the response and perform the global authorization to ensure the corresponding header is injected into all requests.\n- Run `/products/mock` endpoint to generate a set of products.\n- Go to a web browser, refresh the page, and see a list of newly created products. Note that you can also add products one by one from within GUI.\n- Add a couple of products to the cart and click the Cart icon.\n- Open `Need help? See Stripe testing cards` link, copy some test card details, and try to proceed with a test payment.\n\nNote that the flow would be the same in the case of the local and containerized deployment.\n\n[**Go top**](#table-of-contents) :point_up:\n\n### API\n\nThe following endpoints are currently supported and accessible on `http://localhost:9090`.\n\n![API](https://github.com/sskorol/sskorol/assets/6638780/7973a71f-7e80-4a5d-8a95-398e0b33b7e6)\n\n### Tests\n\nThere are no tests. But that's the point. :smirk:\n\nI'd also recommend you perform an exercise by adding custom attributes to elements you'd interact with on FE.\nThat would be a good practice to know your FE better. :mortar_board:\n\n[**Go top**](#table-of-contents) :point_up:\n\n### Credits\n\nInspired by @jayamaljayamaha, who is the author of the original implementation:\n- [backend](https://github.com/jayamaljayamaha/stripe-integration-back-end)\n- [frontend](https://github.com/jayamaljayamaha/stripe-integration-front-end)\n\n[**Go top**](#table-of-contents) :point_up:\n\n### ToDo or Dreams\n\n- [ ] Add API and UI tests using different stacks\n- [ ] Revise and optimize styles\n- [ ] Decouple and optimize FE components\n- [ ] Extend Checkout logic\n- [ ] Add Product details component\n- [ ] Add Product and User management screens\n- [ ] Add file upload support for images\n- [ ] Revise DTOs, possibly add DAOs\n- [x] Add products deletion endpoint\n- [x] Add dynamic environment variables support to FE\n\n[**Go top**](#table-of-contents) :point_up:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsskorol%2Faqa-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsskorol%2Faqa-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsskorol%2Faqa-playground/lists"}