{"id":31746854,"url":"https://github.com/jrpool/testu","last_synced_at":"2025-10-09T13:20:46.789Z","repository":{"id":198080943,"uuid":"700023285","full_name":"jrpool/testu","owner":"jrpool","description":"Ask Testaro to test a web page for accessibility","archived":false,"fork":false,"pushed_at":"2024-06-15T02:23:41.000Z","size":875,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-15T20:58:41.539Z","etag":null,"topics":["accessibility","testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/jrpool.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-10-03T19:48:44.000Z","updated_at":"2024-06-15T02:23:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"41e0b1ba-3501-4a02-96bf-c3ab9e362bf2","html_url":"https://github.com/jrpool/testu","commit_stats":null,"previous_names":["jrpool/testu"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jrpool/testu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrpool%2Ftestu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrpool%2Ftestu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrpool%2Ftestu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrpool%2Ftestu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jrpool","download_url":"https://codeload.github.com/jrpool/testu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrpool%2Ftestu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001536,"owners_count":26083102,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["accessibility","testing"],"created_at":"2025-10-09T13:20:43.917Z","updated_at":"2025-10-09T13:20:46.783Z","avatar_url":"https://github.com/jrpool.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# testu\nAsk Testaro to test a web page for accessibility\n\n## Introduction\n\nTestu is a web-based demonstration user interface for ensemble testing of web accessibility. It uses [Testaro](https://www.npmjs.com/package/testaro) and [Testilo](https://www.npmjs.com/package/testilo) to perform and report tests of a web page.\n\nThe purpose of Testu is to allow users to experience the functionalities of Testaro and Testilo with minimal effort. Users identify a web page to be tested, and Testu does everything else.\n\n## Architecture\n\nAn application that uses Testaro and Testilo to test and report the accessibility of a web page must choose how to handle the time that elapses from the user’s request to the delivery of results. That time is typically 3 minutes, but can be double that when the page being tested is complex, large, or slow.\n\nOne strategy is to acknowledge the request immediately and send the user a message when the work is complete, with a link to a document containing results.\n\nAnother strategy is to keep the web connection open and give incremental updates to the user describing progress, with the final update providing the results or a link to the results.\n\nTestu adopts this second strategy, so it has no need to collect messaging addresses from users and transmit non-web messages. Testu uses server-sent events in order to provide the updates.\n\nTestilo is a dependency of Testu. Testu uses Testilo to prepare jobs for Testaro and to convert Testaro reports into web-based human-oriented digests.\n\nTestaro is not a dependency of Testu. Testaro is installed on one or more workstations. Each such instance of Testaro is called an “agent”. It watches for jobs from the server that deploys Testu. More precisely, the agent periodically contacts the server to ask whether the server has a job for Testaro to perform.\n\nWhen a user asks Testu to test a web page, Testu creates a job and assigns it to the next agent that asks for a job. While the agent works on the job, the agent sends updates to Testu, which Testu converts into server-sent events and forwards to the user agent. When the agent finishes the job, the agent sends its report to Testu, which uses Testilo to further process the report and create a web-based digest. Testu then completes its response to the user agent with a link to the digest, which in turn contains a link to the full JSON report.\n\n## Deployment\n\nOne deployment of Testu is described here.\n\nTestu was deployed on an Amazon Web Services (AWS) EC2 server with an Ubuntu image. The deployment process was based, in part, on [Digital Ocean documentation on Node](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04), [on Nginx](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04), and [on Certbot](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04). The process was as follows:\n1. Create an instance on AWS with the Ubuntu operating system, `t2-micro` type, and 30GiB non-encrypted SSD storage.\n1. Connect to it in the AWS Console.\n1. Do not install `git`, because it is already installed.\n1. Install `nodejs` per `https://github.com/nodesource/distributions#installation-instructions`.\n1. Install `build-essential` (`sudo apt-get install build-essential`).\n1. Install PM2 (`sudo npm install -g pm2@latest`).\n1. Configure PM2 to restart `testu` when the server is rebooted (`pm2 startup systemd` plus the additional statement returned by that statement).\n1. Save the PM2 process list and environments (`pm2 save`).\n1. Try to start PM2 (`sudo systemctl start pm2-ubuntu`).\n1. It will fail, so reboot the server (`sudo shutdown -r now`) and wait about 2 minutes.\n1. Connect to the server again with `ssh`.\n1. Start PM2 (`sudo systemctl start pm2-ubuntu`).\n1. Get an elastic IP address from AWS and associate it with the instance.\n1. Get a domain name for the site. The domain name obtained for this site was `testaro.tools`.\n1. Make the domain name point to the site by giving it 2 DNS records:\n    - An `A` record with host `@`, value equal to the elastic IP address, and automatic TTL.\n    - A `CNAME` record with host `www`, value `testaro.tools`, and TTL 30 minutes.\n1. Reboot the instance (`sudo shutdown -r now`).\n1. Upgrade packages (`sudo apt-get upgrade`).\n1. Update the package lists (`sudo apt update`).\n1. If the output says that packages can be upgraded, do that (`sudo apt upgrade`).\n1. If the output recommends rebooting, do that (`sudo shutdown -r now`) and wait about 2 minutes, and then repeat the update and upgrade commands. If the output says some packages are obsolete, remove them (`sudo apt autoremove`).\n1. Install Nginx (`sudo apt-get install nginx`).\n1. Check that Nginx is running and reachable with HTTP by browsing to the server domain name (`testaro.tools`).\n1. Customize the fall-back page that Nginx will serve when Testu is not available by editing the file at `/var/www/html/index.nginx-debian.html`.\n1. Verify that the revision worked by navigating again to the same URL.\n1. Create directories for the main site and web page (`sudo mkdir -p /var/www/testaro.tools/html`).\n1. Make `ubuntu` their owner and group (`sudo chown ubuntu:ubuntu /var/www/testaro.tools /var/www/testaro.tools/html`);\n1. Copy the fall-back page of the server, making it the main web page (`cp /var/www/html/index.nginx-debian.html /var/www/testaro.tools/html/index.html`).\n1. Edit it to make it the main page of the site, with this content:\n\n    ```html\n    \u003c!DOCTYPE html\u003e\n    \u003chtml lang=\"en_US\"\u003e\n      \u003chead\u003e\n        \u003ctitle\u003eWelcome to testaro.tools\u003c/title\u003e\n        \u003cstyle\u003e\n          html {\n            color-scheme: light dark;\n          }\n          body {\n            width: 35rem;\n            margin-left: 5rem;\n          }\n        \u003c/style\u003e\n      \u003c/head\u003e\n      \u003cbody\u003e\n        \u003ch1\u003eWelcome to testaro.tools\u003c/h1\u003e\n        \u003cp\u003eTestaro performs about 960 web accessibility tests from 9 tools.\u003c/p\u003e\n        \u003cp\u003eTestilo makes it easier to use Testaro.\u003c/p\u003e\n        \u003cp\u003e\u003ca href=\"https://testaro.tools/testu\"\u003eTest a web page now\u003c/a\u003e.\u003c/p\u003e\n        \u003cp\u003e\u003ca href=\"https://testaro.tools/scores\"\u003eCompare all pages already tested\u003c/a\u003e.\u003c/p\u003e\n        \u003cp\u003e\u003ca href=\"https://testaro.tools/scores/credit\"\u003eGet tool-issue data from the existing reports\u003c/a\u003e.\u003c/p\u003e\n      \u003c/body\u003e\n    \u003c/html\u003e\n    ```\n\n1. Create a configuration block file for the `testaro.tools` site named `/etc/nginx/sites-available/testaro.tools`. Give it this content:\n\n    ```bash\n    server {\n      listen 80;\n      listen [::]:80;\n      root /var/www/testaro.tools/html;\n      index index.html;\n      server_name testaro.tools www.testaro.tools;\n      location / {\n        try_files $uri $uri/ =404;\n      }\n    }\n    ```\n\n1. Adjust the Nginx configuration to allow multiple sites by removing the `#` on the `server_names_hash_bucket_size 64;` line in the `/etc/nginx/nginx.conf` file.\n1. Check the above work (`sudo nginx -t`).\n1. Restart Nginx (`sudo systemctl restart nginx`).\n1. Verify the above work by navigating to the site (`http://testaro.tools`) with a browser.\n1. Create a symbolic link to the configuration block file where Nginx will find it (`sudo ln -s /etc/nginx/sites-available/testaro.tools /etc/nginx/sites-enabled/`).\n1. Install Certbot (`sudo apt install certbot python3-certbot-nginx`).\n1. Get an SSL certificate (`sudo certbot --nginx -d testaro.tools -d www.testaro.tools`). Doing this revises the `/etc/nginx/sites-available/testaro.tools` file that you created, making Nginx permanently redirect any requests for `http://testaro.tools` to `https://testaro.tools`.\n1. Check the automatic certificate renewal process (`sudo systemctl status certbot.timer`).\n1. Test that process (`sudo certbot renew --dry-run`).\n1. With `/var/www` as the working directory, clone `testu` (`sudo git clone https://github.com/jrpool/testu.git`).\n1. Change the owner and group of the `testu` directory and all subdirectories and files in it to `ubuntu` (`sudo chown -R ubuntu:ubuntu /var/www/testu`).\n1. Make `git` accept `ubuntu` as the owner of the `testu` directory (`git config --global --add safe.directory /var/www/testu`).\n1. Add an `.env` file to the `/var/www/testu` directory, containing these environment variables (replacing `abc+xyz` with a `+`-delimited list of authorized testing agent IDs and replacing `ts…` with a script ID such as `ts99`):\n\n    ```bash\n    APP_URL=https://testaro.tools/testu\n    PROTOCOL=http\n    REQUESTER=demo@testaro.tools\n    AGENTS=abc+xyz\n    SCRIPT=ts…\n    REJECT_UNAUTHORIZED=true\n    ```\n\n1. Create an `.npmrc` file in `/home/ubuntu` with your username and authorization token for NPM replacing “…”:\n    - `//registry.npmjs.org/:_username=…`\n    - //`registry.npmjs.org/:_authToken=npm_…`\n1. Change its mode so only the user can read or write.\n1. Delete the `package-lock.json` file in `/var/www/testu` to avoid the password bug.\n1. With `/var/www/testu` as the working directory, install the Testu dependencies (`npm install`).\n1. Check Testu with `node index`, then `^C` to quit.\n1. Use PM2 to start Testu without watching (`pm2 start index.js --name testu`). Watching is convenient for development, but it ruins the operation of Testu, because it restarts Testu whenever Testu writes a file. So, when you make changes to the code, you will need to restart PM2 (`pm2 restart testu`).\n1. Edit `/etc/nginx/sites-available/testaro.tools` (previously revised by Certbot), to make Nginx hand HTTPS `testu` requests to the `testu` application on port 3008, as HTTP requests. Specifically, add a second `location` block immediately before or after the existing one (the order does not matter, because Nginx chooses the location with the longest matching prefix, and `/testu` is longer than `/`). The new `location` block is:\n\n    ```bash\n    location /testu {\n      proxy_pass http://localhost:3008;\n      proxy_http_version 1.1;\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection '';\n      proxy_set_header Host $host;\n      proxy_cache_bypass $http_upgrade;\n    }\n    ```\n\n1. Reload Nginx to use this configuration (`sudo systemctl reload nginx`).\n1. Test Nginx as a reverse proxy and Testu by navigating to:\n- `https://testaro.tools`\n- `http://testaro.tools`\n- `https://testaro.tools/testu`\n- `http://testaro.tools/testu`\n\n## Configuration\n\nTo allow testing of pages whose SSL certificates are self-signed or have unrecognized certificate authorities, you can change the value of `REJECT_UNAUTHORIZED` in the `.env` file to `false`.\n\nTestu must accept job requests from at least one Testaro agent. The list of accepted agents is a `+`-delimited string that is the value of `AGENTS` in the `.env` file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrpool%2Ftestu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjrpool%2Ftestu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrpool%2Ftestu/lists"}