mirror of
https://github.com/leptos-rs/leptos
synced 2024-09-20 06:21:57 +00:00
test(counters_stable): add playwright tests (#1235)
This commit is contained in:
parent
c3e45d19d7
commit
f5cfe4e8a2
21 changed files with 537 additions and 6 deletions
|
@ -34,7 +34,7 @@ category = "Cleanup"
|
|||
script = '''
|
||||
for pw_dir in $(find . -name playwright.config.ts | xargs dirname)
|
||||
do
|
||||
rm -rf $pw_dir/playwright-report
|
||||
rm -rf $pw_dir/playwright-report pw_dir/playwright pw_dir/test-results
|
||||
done
|
||||
'''
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
extend = [{ path = "../cargo-make/common.toml" }]
|
||||
|
||||
[tasks.ci]
|
||||
alias = "verify-flow"
|
||||
|
||||
[tasks.verify-flow]
|
||||
description = "Provides pre and post hooks for verify"
|
||||
dependencies = ["pre-verify", "verify", "post-verify"]
|
||||
|
|
7
examples/cargo-make/playwright-test.toml
Normal file
7
examples/cargo-make/playwright-test.toml
Normal file
|
@ -0,0 +1,7 @@
|
|||
extend = [{ path = "../cargo-make/playwright.toml" }]
|
||||
|
||||
[tasks.test-e2e]
|
||||
dependencies = ["setup-node", "test-playwright-autostart"]
|
||||
|
||||
[tasks.clean-all]
|
||||
dependencies = ["clean-cargo", "clean-node_modules", "clean-playwright"]
|
119
examples/cargo-make/playwright.toml
Normal file
119
examples/cargo-make/playwright.toml
Normal file
|
@ -0,0 +1,119 @@
|
|||
[tasks.clean-playwright]
|
||||
description = "Delete playwright directories"
|
||||
category = "Cleanup"
|
||||
script = '''
|
||||
for pw_dir in $(find . -name playwright.config.ts | xargs dirname)
|
||||
do
|
||||
rm -rf $pw_dir/playwright-report pw_dir/playwright pw_dir/test-results
|
||||
done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-autostart]
|
||||
description = "Run playwright test with server autostart"
|
||||
category = "Test"
|
||||
command = "npm"
|
||||
args = ["run", "e2e:auto-start"]
|
||||
|
||||
[tasks.test-playwright]
|
||||
description = "Run playwright test"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
RED="\e[0;31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
project_dir=$CARGO_MAKE_WORKING_DIRECTORY
|
||||
|
||||
# Discover commands
|
||||
if command -v pnpm; then
|
||||
PLAYWRIGHT_CMD=pnpm
|
||||
elif command -v npm; then
|
||||
PLAYWRIGHT_CMD=npx
|
||||
else
|
||||
echo "${RED}${BOLD}ERROR${RESET} - pnpm or npm is required by this task"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run playwright command
|
||||
for pw_path in $(find . -name playwright.config.ts)
|
||||
do
|
||||
pw_dir=$(dirname $pw_path)
|
||||
cd $pw_dir
|
||||
${PLAYWRIGHT_CMD} playwright test
|
||||
cd $project_dir
|
||||
done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-ui]
|
||||
description = "Run playwright test --ui"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
RED="\e[0;31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
project_dir=$CARGO_MAKE_WORKING_DIRECTORY
|
||||
|
||||
# Discover commands
|
||||
if command -v pnpm; then
|
||||
PLAYWRIGHT_CMD=pnpm
|
||||
elif command -v npm; then
|
||||
PLAYWRIGHT_CMD=npx
|
||||
else
|
||||
echo "${RED}${BOLD}ERROR${RESET} - pnpm or npm is required by this task"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run playwright command
|
||||
for pw_path in $(find . -name playwright.config.ts)
|
||||
do
|
||||
pw_dir=$(dirname $pw_path)
|
||||
cd $pw_dir
|
||||
${PLAYWRIGHT_CMD} playwright test --ui
|
||||
cd $project_dir
|
||||
done
|
||||
'''
|
||||
|
||||
[tasks.test-playwright-report]
|
||||
description = "Run playwright show-report"
|
||||
category = "Test"
|
||||
script = '''
|
||||
BOLD="\e[1m"
|
||||
GREEN="\e[0;32m"
|
||||
RED="\e[0;31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
project_dir=$CARGO_MAKE_WORKING_DIRECTORY
|
||||
|
||||
# Discover commands
|
||||
if command -v pnpm; then
|
||||
PLAYWRIGHT_CMD=pnpm
|
||||
elif command -v npm; then
|
||||
PLAYWRIGHT_CMD=npx
|
||||
else
|
||||
echo "${RED}${BOLD}ERROR${RESET} - pnpm or npm is required by this task"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run playwright command
|
||||
for pw_path in $(find . -name playwright.config.ts)
|
||||
do
|
||||
pw_dir=$(dirname $pw_path)
|
||||
cd $pw_dir
|
||||
${PLAYWRIGHT_CMD} playwright show-report
|
||||
cd $project_dir
|
||||
done
|
||||
'''
|
||||
|
||||
# ALIASES
|
||||
|
||||
[tasks.pw]
|
||||
dependencies = ["test-playwright"]
|
||||
|
||||
[tasks.pw-ui]
|
||||
dependencies = ["test-playwright-ui"]
|
||||
|
||||
[tasks.pw-report]
|
||||
dependencies = ["test-playwright-report"]
|
22
examples/cargo-make/trunk_server.toml
Normal file
22
examples/cargo-make/trunk_server.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[tasks.build]
|
||||
command = "trunk"
|
||||
args = ["build"]
|
||||
|
||||
[tasks.clean-trunk]
|
||||
command = "trunk"
|
||||
args = ["clean"]
|
||||
|
||||
[tasks.start-trunk]
|
||||
command = "trunk"
|
||||
args = ["serve", "--open"]
|
||||
|
||||
[tasks.stop-trunk]
|
||||
script = '''
|
||||
pkill -f "cargo-make"
|
||||
pkill -f "trunk"
|
||||
'''
|
||||
|
||||
# ALIASES
|
||||
|
||||
[tasks.dev]
|
||||
dependencies = ["start-trunk"]
|
20
examples/counters_stable/.gitignore
vendored
Normal file
20
examples/counters_stable/.gitignore
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# Support playwright testing
|
||||
node_modules/
|
||||
test-results/
|
||||
end2end/playwright-report/
|
||||
playwright/.cache/
|
||||
pnpm-lock.yaml
|
||||
|
||||
# Support trunk
|
||||
dist
|
|
@ -1,4 +1,8 @@
|
|||
extend = [{ path = "../cargo-make/main.toml" }]
|
||||
extend = [
|
||||
{ path = "../cargo-make/main.toml" },
|
||||
{ path = "../cargo-make/trunk_server.toml" },
|
||||
{ path = "../cargo-make/playwright-test.toml" },
|
||||
]
|
||||
|
||||
[tasks.build]
|
||||
command = "cargo"
|
||||
|
|
4
examples/counters_stable/e2e/.gitignore
vendored
Normal file
4
examples/counters_stable/e2e/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
83
examples/counters_stable/e2e/package-lock.json
generated
Normal file
83
examples/counters_stable/e2e/package-lock.json
generated
Normal file
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"name": "grip",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "grip",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.35.1"
|
||||
}
|
||||
},
|
||||
"node_modules/.pnpm/@playwright+test@1.33.0": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/.pnpm/@types+node@20.2.1/node_modules/@types/node": {
|
||||
"version": "20.2.1",
|
||||
"extraneous": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/.pnpm/playwright-core@1.33.0/node_modules/playwright-core": {
|
||||
"version": "1.33.0",
|
||||
"extraneous": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.35.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.35.1.tgz",
|
||||
"integrity": "sha512-b5YoFe6J9exsMYg0pQAobNDR85T1nLumUYgUTtKm4d21iX2L7WqKq9dW8NGJ+2vX0etZd+Y7UeuqsxDXm9+5ZA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.35.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
|
||||
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.35.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.35.1.tgz",
|
||||
"integrity": "sha512-pNXb6CQ7OqmGDRspEjlxE49w+4YtR6a3X6mT1hZXeJHWmsEz7SunmvZeiG/+y1yyMZdHnnn73WKYdtV1er0Xyg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
examples/counters_stable/e2e/package.json
Normal file
7
examples/counters_stable/e2e/package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"private": "true",
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.35.1"
|
||||
}
|
||||
}
|
77
examples/counters_stable/e2e/playwright.config.ts
Normal file
77
examples/counters_stable/e2e/playwright.config.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./tests",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 10 : 10,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : 1,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "list",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://127.0.0.1:8080",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
|
||||
// {
|
||||
// name: "firefox",
|
||||
// use: { ...devices["Desktop Firefox"] },
|
||||
// },
|
||||
|
||||
// {
|
||||
// name: "webkit",
|
||||
// use: { ...devices["Desktop Safari"] },
|
||||
// },
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ..devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
// webServer: {
|
||||
// command: "cd ../ && trunk serve",
|
||||
// url: "http://127.0.0.1:8080",
|
||||
// reuseExistingServer: false, //!process.env.CI,
|
||||
// },
|
||||
});
|
23
examples/counters_stable/e2e/tests/add_1k_counters.spec.ts
Normal file
23
examples/counters_stable/e2e/tests/add_1k_counters.spec.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("Add 1000 Counters", () => {
|
||||
test("should increment the total count by 1K", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
|
||||
// FIXME: Uncomment to make the test fail consistently
|
||||
|
||||
await ui.addOneThousandCounters();
|
||||
// await expect(ui.total).toHaveText("0");
|
||||
// await expect(ui.counters).toHaveText("1000");
|
||||
|
||||
await ui.addOneThousandCounters();
|
||||
// await expect(ui.total).toHaveText("0");
|
||||
// await expect(ui.counters).toHaveText("2000");
|
||||
|
||||
await ui.addOneThousandCounters();
|
||||
await expect(ui.total).toHaveText("0");
|
||||
await expect(ui.counters).toHaveText("3000");
|
||||
});
|
||||
});
|
16
examples/counters_stable/e2e/tests/add_counter.spec.ts
Normal file
16
examples/counters_stable/e2e/tests/add_counter.spec.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("Add Counter", () => {
|
||||
test("should increment the total count", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
|
||||
await ui.addCounter();
|
||||
await ui.addCounter();
|
||||
await ui.addCounter();
|
||||
|
||||
await expect(ui.total).toHaveText("0");
|
||||
await expect(ui.counters).toHaveText("3");
|
||||
});
|
||||
});
|
18
examples/counters_stable/e2e/tests/clear_counters.spec.ts
Normal file
18
examples/counters_stable/e2e/tests/clear_counters.spec.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("Clear Counters", () => {
|
||||
test("should reset the counts", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
|
||||
await ui.addCounter();
|
||||
await ui.addCounter();
|
||||
await ui.addCounter();
|
||||
|
||||
await ui.clearCounters();
|
||||
|
||||
await expect(ui.total).toHaveText("0");
|
||||
await expect(ui.counters).toHaveText("0");
|
||||
});
|
||||
});
|
63
examples/counters_stable/e2e/tests/counters_page.ts
Normal file
63
examples/counters_stable/e2e/tests/counters_page.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { expect, Locator, Page } from "@playwright/test";
|
||||
|
||||
export class CountersPage {
|
||||
readonly page: Page;
|
||||
readonly addCounterButton: Locator;
|
||||
readonly addOneThousandCountersButton: Locator;
|
||||
readonly clearCountersButton: Locator;
|
||||
readonly decrementCountButton: Locator;
|
||||
readonly incrementCountButton: Locator;
|
||||
|
||||
readonly total: Locator;
|
||||
readonly counters: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
|
||||
this.addCounterButton = page.locator("button", { hasText: "Add Counter" });
|
||||
|
||||
this.addOneThousandCountersButton = page.locator("button", {
|
||||
hasText: "Add 1000 Counters",
|
||||
});
|
||||
|
||||
this.clearCountersButton = page.locator("button", {
|
||||
hasText: "Clear Counters",
|
||||
});
|
||||
|
||||
this.decrementCountButton = page.locator("button", {
|
||||
hasText: "-1",
|
||||
});
|
||||
|
||||
this.incrementCountButton = page.locator("button", {
|
||||
hasText: "+1",
|
||||
});
|
||||
|
||||
this.total = page.getByTestId("total");
|
||||
|
||||
this.counters = page.getByTestId("counters");
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto("/");
|
||||
}
|
||||
|
||||
async addCounter() {
|
||||
this.addCounterButton.click();
|
||||
}
|
||||
|
||||
async addOneThousandCounters() {
|
||||
this.addOneThousandCountersButton.click();
|
||||
}
|
||||
|
||||
async decrementCount() {
|
||||
this.decrementCountButton.click();
|
||||
}
|
||||
|
||||
async incrementCount() {
|
||||
this.incrementCountButton.click();
|
||||
}
|
||||
|
||||
async clearCounters() {
|
||||
this.clearCountersButton.click();
|
||||
}
|
||||
}
|
17
examples/counters_stable/e2e/tests/decrement_count.spec.ts
Normal file
17
examples/counters_stable/e2e/tests/decrement_count.spec.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("Decrement Count", () => {
|
||||
test("should decrement the total count", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
await ui.addCounter();
|
||||
|
||||
await ui.decrementCount();
|
||||
await ui.decrementCount();
|
||||
await ui.decrementCount();
|
||||
|
||||
await expect(ui.total).toHaveText("-3");
|
||||
await expect(ui.counters).toHaveText("1");
|
||||
});
|
||||
});
|
17
examples/counters_stable/e2e/tests/increment_count.spec.ts
Normal file
17
examples/counters_stable/e2e/tests/increment_count.spec.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("Increment Count", () => {
|
||||
test("should increment the total count", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
await ui.addCounter();
|
||||
|
||||
await ui.incrementCount();
|
||||
await ui.incrementCount();
|
||||
await ui.incrementCount();
|
||||
|
||||
await expect(ui.total).toHaveText("3");
|
||||
await expect(ui.counters).toHaveText("1");
|
||||
});
|
||||
});
|
19
examples/counters_stable/e2e/tests/view_counters.spec.ts
Normal file
19
examples/counters_stable/e2e/tests/view_counters.spec.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { CountersPage } from "./counters_page";
|
||||
|
||||
test.describe("View Counters", () => {
|
||||
test("should_see_the_title", async ({ page }) => {
|
||||
const ui = new CountersPage(page);
|
||||
await ui.goto();
|
||||
|
||||
await expect(page).toHaveTitle("Counters (Stable)");
|
||||
});
|
||||
|
||||
test("should see the initial counts", async ({ page }) => {
|
||||
const counters = new CountersPage(page);
|
||||
await counters.goto();
|
||||
|
||||
await expect(counters.total).toHaveText("0");
|
||||
await expect(counters.counters).toHaveText("0");
|
||||
});
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Counters (Stable)</title>
|
||||
<link data-trunk rel="rust" data-wasm-opt="z" data-weak-refs/>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
11
examples/counters_stable/package.json
Normal file
11
examples/counters_stable/package.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"private": "true",
|
||||
"scripts": {
|
||||
"start-server": "trunk serve",
|
||||
"e2e": "cargo make test-playwright",
|
||||
"e2e:auto-start": "start-server-and-test start-server http://127.0.0.1:8080 e2e"
|
||||
},
|
||||
"devDependencies": {
|
||||
"start-server-and-test": "^1.15.4"
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ pub fn Counters(cx: Scope) -> impl IntoView {
|
|||
</button>
|
||||
<p>
|
||||
"Total: "
|
||||
<span>{move ||
|
||||
<span id="total" data-testid="total">{move ||
|
||||
counters.get()
|
||||
.iter()
|
||||
.map(|(_, (count, _))| count.get())
|
||||
|
@ -64,7 +64,7 @@ pub fn Counters(cx: Scope) -> impl IntoView {
|
|||
.to_string()
|
||||
}</span>
|
||||
" from "
|
||||
<span>{move || counters.with(|counters| counters.len()).to_string()}</span>
|
||||
<span id="counters" data-testid="counters">{move || counters.with(|counters| counters.len()).to_string()}</span>
|
||||
" counters."
|
||||
</p>
|
||||
<ul>
|
||||
|
@ -99,13 +99,13 @@ fn Counter(
|
|||
|
||||
view! { cx,
|
||||
<li>
|
||||
<button on:click=move |_| set_value.update(move |value| *value -= 1)>"-1"</button>
|
||||
<button id="decrement_count" on:click=move |_| set_value.update(move |value| *value -= 1)>"-1"</button>
|
||||
<input type="text"
|
||||
prop:value={move || value.get().to_string()}
|
||||
on:input=input
|
||||
/>
|
||||
<span>{move || value.get().to_string()}</span>
|
||||
<button on:click=move |_| set_value.update(move |value| *value += 1)>"+1"</button>
|
||||
<button id="increment_count" on:click=move |_| set_value.update(move |value| *value += 1)>"+1"</button>
|
||||
<button on:click=move |_| set_counters.update(move |counters| counters.retain(|(counter_id, _)| counter_id != &id))>"x"</button>
|
||||
</li>
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue