Web Dev Solutions

Catalin Mititiuc

## Install dev server packages docker run --rm -w /app -v $PWD:/app -u $(id -u):$(id -u) node npm install ## Start the dev server docker run --rm --init -it -v $PWD:/usr/src/app -p 8080:8080 btroops or, run the start script ./run-start Visit `localhost:8080` to view. ## Run a test You need chrome and chromedriver installed to run the integration tests. The Dockerfile builds an image that does that. Then run the test with that image. `--network host` gives the container internet access. Necessary if tests make outside requests. docker run --rm -it -v $PWD:/usr/src/app --network host btroops node google_test TODO add firefox and geckodriver The container can access the outside without setting a port or a network. The network or port is only necessary when wanting to connect the host machine to the docker container. You can run a test that spawns a test server and uses the webdriver to load the page like this: docker run --rm -it -v $PWD:/usr/src/app btroops npm run test:integ or, run the test script ./run-test ### Debugging a Jest integration test `page.test.js` ```javascript // webdriver setup here it('loads the page', async () => { await driver.get("http://localhost:3005"); expect(await driver.getTitle()).toEqual('Infantry Combat Solo Basic'); // where you want your breakpoint debugger; // necessary for restarting from the debugger to work driver.quit(); }); ``` Start the container with a bash prompt. docker run --rm --init -it -v $PWD:/usr/src/app btroops bash Start the debugger with Jest integration test setup NODE_INSPECT_RESUME_ON_START=1 node inspect ./node_modules/jest/bin/jest.js --config jest.config.integ.cjs --runInBand test/integration/page.test.js You can do the whole thing in one command like this. docker run --rm --init -it -v $PWD:/usr/src/app -e NODE_INSPECT_RESUME_ON_START=1 btroops node inspect ./node_modules/jest/bin/jest.js --config jest.config.integ.cjs --runInBand test/integration/page.test.js ``` < Debugger listening on ws://127.0.0.1:9229/bcaf4c18-b204-49c6-8ccf-600fe8be0506 < For help, see: https://nodejs.org/en/docs/inspector < connecting to 127.0.0.1:9229 ... ok < Debugger attached. < < Jest config file read. < < < Spawning server process... < < Development server running at http://localhost:3005 < Build completed in 10ms < < break in test/integration/page.test.js:26 24 await counter.click(); 25 expect(await counter.getAttribute('class')).toEqual(expect.stringContaining('selected')); >26 debugger; 27 }); 28 afterAll(() => driver.quit()); debug> ``` To run the test again without having to quit the debugger, use `c` to continue past the breakpoint and then `r` to restart. ``` debug> c < PASS test/integration/page.test.js (141.892 s) < < ✓ loads the page (8 ms) < < ✓ selects a trooper by clicking on their counter (140792 ms) < < < Test Suites: 1 passed, 1 total < Tests: 2 passed, 2 total < Snapshots: 0 total < Time: 141.925 s < Ran all test suites matching /test\/integration\/page.test.js/i. < < Stopping server. < < Waiting for the debugger to disconnect... < debug> r < Debugger listening on ws://127.0.0.1:9229/9ba4c56c-03ff-46c4-92d1-3b519374d1be < For help, see: https://nodejs.org/en/docs/inspector < connecting to 127.0.0.1:9229 ... ok < Debugger attached. < < Jest config file read. < < < Spawning server process... < < Development server running at http://localhost:3005 < Build completed in 11ms < < break in test/integration/page.test.js:26 24 await counter.click(); 25 expect(await counter.getAttribute('class')).toEqual(expect.stringContaining('selected')); >26 debugger; 27 }); 28 afterAll(() => driver.quit()); debug> ``` ### References https://nodejs.org/en/learn/getting-started/debugging https://nodejs.org/api/debugger.html ## Rough way to save the SVG map generated by JavaScript client-side const XMLS = new XMLSerializer(); const svg_xmls = XMLS.serializeToString(svg); let bl = new Blob([svg_xmls], {type: "text/html" }); let a = document.createElement("a"); a.href = URL.createObjectURL(bl); a.download = "map.svg"; a.hidden = true; document.body.appendChild(a); a.innerHTML = "something random - nobody will see this, it doesn't matter what you put here"; a.click()