diff --git a/.github/workflows/verify-pr.yml b/.github/workflows/verify-pr.yml index e3469fc9..a6c61ecd 100644 --- a/.github/workflows/verify-pr.yml +++ b/.github/workflows/verify-pr.yml @@ -27,6 +27,10 @@ jobs: with: node-version: 20 - run: yarn install --frozen-lockfile + - run: yarn run check + - name: Install Playwright + run: npx playwright install + - run: yarn run test - run: yarn run build env: PUBLIC_CAPTCHA_KEY: 6LesXHomAAAAAGVVTCgc467t8hvBbmK7IlYZCc8O @@ -35,16 +39,11 @@ jobs: PUBLIC_DEMO_MODE: false GITHUB_PAGES: "/${{ github.event.repository.name }}" STATIC: true - - run: yarn run check - - name: Install Playwright - run: npx playwright install - - run: yarn run test - uses: actions/upload-artifact@master with: name: faucet path: ./client/build if-no-files-found: error - - run: yarn run check test-image: runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index dc1cede2..1d7e3784 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .idea +.last-run.json +test-results .env node_modules .yarn diff --git a/client/env.sample b/client/env.sample new file mode 100644 index 00000000..edd40f82 --- /dev/null +++ b/client/env.sample @@ -0,0 +1,4 @@ + PUBLIC_DEMO_MODE=false + PUBLIC_CAPTCHA_KEY=6LesXHomAAAAAGVVTCgc467t8hvBbmK7IlYZCc8O + PUBLIC_FORUM="" + PUBLIC_FAUCET_URL="" diff --git a/client/package.json b/client/package.json index 7a5b9057..2e34f329 100644 --- a/client/package.json +++ b/client/package.json @@ -22,6 +22,7 @@ "autoprefixer": "^10.4.16", "daisyui": "^4.4.4", "postcss": "^8.4.47", + "postcss-load-config": "^6.0.1", "svelte": "^4.2.19", "svelte-check": "^4.0.2", "svelte-markdown": "^0.4.1", diff --git a/client/tests/faucet.ts b/client/tests/faucet.ts index 52c7c1ed..441edcd9 100644 --- a/client/tests/faucet.ts +++ b/client/tests/faucet.ts @@ -88,6 +88,8 @@ export class FaucetTests { }; runTests(): void { + const validAddress = '5G3r2K1cEi4vtdBjMNHpjWCofRdyg2AFSdVVxMGkDGvuJgaG'; + test.describe(`${this.faucetName} tests`, () => { test.describe("on page load", () => { test("page has expected header", async ({ page }) => { @@ -199,17 +201,27 @@ export class FaucetTests { await page.goto(this.url); const { address, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - await address.fill("address"); + await address.fill(validAddress); await captcha.click(); await expect(submit).toBeEnabled(); }); + test("Shows address invalid message when invalid address is entered", async ({page}, {config}) => { + await page.goto(this.url); + const { address, captcha, submit } = await getFormElements(page, true); + const expectedErrorMessage = "Address is invalid"; + await address.fill('garbage'); + await captcha.click(); + const errorMessage = page.getByTestId("error"); + await expect(errorMessage).toBeVisible(); + expect((await errorMessage.allInnerTexts())[0]).toContain(expectedErrorMessage); + }) + test("sends data on submit", async ({ page }, { config }) => { await page.goto(this.url); const { address, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - const myAddress = "0x000000001"; - await address.fill(myAddress); + await address.fill(validAddress); await captcha.click(); const faucetUrl = this.getFaucetUrl(config); @@ -220,7 +232,7 @@ export class FaucetTests { const request = page.waitForRequest((req) => { if (req.url() === faucetUrl) { const data = req.postDataJSON() as FormSubmit; - expect(data.address).toEqual(myAddress); + expect(data.address).toEqual(validAddress); return !!data.recaptcha; } return false; @@ -237,8 +249,7 @@ export class FaucetTests { const { address, captcha, submit } = await getFormElements(page, true); const dropdown = page.getByTestId(this.dropdownId); await expect(submit).toBeDisabled(); - const myAddress = "0x000000002"; - await address.fill(myAddress); + await address.fill(validAddress); await dropdown.click(); const networkBtn = page.getByTestId(`network-${i}`); await expect(networkBtn).toBeVisible(); @@ -254,7 +265,7 @@ export class FaucetTests { if (req.url() === faucetUrl) { const data = req.postDataJSON() as FormSubmit; const parachain_id = chain.id > 0 ? chain.id.toString() : undefined; - expect(data).toMatchObject({ address: myAddress, parachain_id }); + expect(data).toMatchObject({ address: validAddress, parachain_id }); return !!data.recaptcha; } return false; @@ -269,8 +280,7 @@ export class FaucetTests { await page.goto(this.url); const { address, network, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - const myAddress = "0x000000002"; - await address.fill(myAddress); + await address.fill(validAddress); const customChainDiv = page.getByTestId("custom-network-button"); await customChainDiv.click(); await network.fill("9999"); @@ -284,7 +294,7 @@ export class FaucetTests { const request = page.waitForRequest((req) => { if (req.url() === faucetUrl) { const data = req.postDataJSON() as FormSubmit; - expect(data).toMatchObject({ address: myAddress, parachain_id: "9999" }); + expect(data).toMatchObject({ address: validAddress, parachain_id: "9999" }); return !!data.recaptcha; } return false; @@ -299,8 +309,7 @@ export class FaucetTests { const operationHash = "0x0123435423412343214"; const { address, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - const myAddress = "0x000000001"; - await address.fill(myAddress); + await address.fill(validAddress); await captcha.click(); await page.route(this.getFaucetUrl(config), (route) => route.fulfill({ body: JSON.stringify({ hash: operationHash }) }) @@ -320,7 +329,7 @@ export class FaucetTests { const error = "Things failed because you are a naughty boy!"; const { address, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - await address.fill("0x123"); + await address.fill(validAddress); await captcha.click(); await page.route(this.getFaucetUrl(config), (route) => route.fulfill({ body: JSON.stringify({ error }) }) diff --git a/client/tests/test.ts b/client/tests/test.ts index d0ff1e02..a2c144f0 100644 --- a/client/tests/test.ts +++ b/client/tests/test.ts @@ -15,6 +15,8 @@ type FormSubmit = { parachain_id?: string; }; +const testAddress = '5G3r2K1cEi4vtdBjMNHpjWCofRdyg2AFSdVVxMGkDGvuJgaG'; + const getFormElements = async (page: Page, getCaptcha = false) => { let captcha: Locator = {} as Locator; if (getCaptcha) { @@ -115,7 +117,7 @@ test.describe("form interaction", () => { await page.goto("/"); const { address, captcha, submit } = await getFormElements(page, true); await expect(submit).toBeDisabled(); - await address.fill("address"); + await address.fill(testAddress); await captcha.click(); await expect(submit).toBeEnabled(); }); diff --git a/client/yarn.lock b/client/yarn.lock index a9666227..bbf73943 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -1198,6 +1198,11 @@ lilconfig@^3.0.0: resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz" integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== +lilconfig@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" @@ -1438,6 +1443,13 @@ postcss-load-config@^4.0.1: lilconfig "^3.0.0" yaml "^2.3.4" +postcss-load-config@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz#6fd7dcd8ae89badcf1b2d644489cbabf83aa8096" + integrity sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g== + dependencies: + lilconfig "^3.1.1" + postcss-nested@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz"