Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 1-Identities-and-Names/identity-withdraw-credits.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ console.log('Identity balance before withdrawal:', identity.balance);
// Default: testnet faucet address. Replace or override via WITHDRAWAL_ADDRESS.
const toAddress =
process.env.WITHDRAWAL_ADDRESS || 'yXWJGWuD4VBRMp9n2MtXQbGpgSeWyTRHme';
const amount = 190000n; // Credits to withdraw
const amount = 1000000n; // Credits to withdraw (protocol minimum)
const amountDash = Number(amount) / (1000 * 100000000);

console.log(`Withdrawing ${amount} credits (${amountDash} DASH)`);
Expand Down
39 changes: 8 additions & 31 deletions example-apps/dashmint-lab/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example-apps/dashmint-lab/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"preview": "vite preview"
},
"dependencies": {
"@dashevo/evo-sdk": "4.0.0-rc.1",
"@dashevo/evo-sdk": "4.0.0-rc.2",
"@tailwindcss/vite": "^4.2.2",
"react": "^19.2.4",
"react-dom": "^19.2.4",
Expand Down
2 changes: 1 addition & 1 deletion example-apps/dashmint-lab/public/dashmint-lite.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ <h2>Browse cards</h2>
// package and serves it as a browser-native ES module. Pinned to the same
// version the React app at ../package.json depends on so both UIs behave
// identically against the same testnet contract.
import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@3.1.0-dev.6';
import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@4.0.0-rc.2';

// The token-enabled "card" data contract is already published on testnet by
// the React app. Anyone querying with the same contract id hits the same
Expand Down
27 changes: 15 additions & 12 deletions example-apps/dashmint-lab/test/e2e/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,6 @@ test.describe("Authenticated flows (auth-gated)", () => {
}) => {
await loginViaModal(page);

// Read the truncated identity id from the IdentityCard so we can skip
// self-listings.
const myIdSnippet = await page
.locator("aside")
.getByText(/[1-9A-HJ-NP-Za-km-z]{6}…[1-9A-HJ-NP-Za-km-z]{6}/)
.first()
.textContent();
const myPrefix = myIdSnippet?.split("…")[0]?.trim();

await page.getByRole("button", { name: "Marketplace" }).click();
await expect(page.getByText(/loading…/i)).toBeHidden({ timeout: 90_000 });

Expand All @@ -98,10 +89,16 @@ test.describe("Authenticated flows (auth-gated)", () => {
test.skip(true, "Marketplace is empty.");
}

// A listing the test identity could purchase is exactly one rendered with
// a "Buy" button — CardTile only shows it for non-owner listings (owned
// listings get "Sell"/"Edit price" instead). Selecting by this button
// sidesteps owner-chip string matching, which breaks when the test
// identity has a DPNS name (the chip shows "@username", not the truncated
// identity id we used to compare against).
let target = -1;
for (let i = 0; i < count; i += 1) {
const text = await cards.nth(i).innerText();
if (!myPrefix || !text.includes(myPrefix)) {
const buyBtn = cards.nth(i).getByRole("button", { name: /^buy$/i });
if (await buyBtn.isVisible().catch(() => false)) {
target = i;
break;
}
Expand All @@ -122,7 +119,13 @@ test.describe("Authenticated flows (auth-gated)", () => {
await expect(
dialog.getByText(/\d[\d,]*\s*(cr|credits)/i).first(),
).toBeVisible();
await expect(dialog.getByRole("button", { name: /^Buy/ })).toBeVisible();
// The primary button is enabled "Buy" for an affordable listing, or
// disabled "Insufficient credits" when the listing's price exceeds the
// test identity's balance (PurchaseModal does the affordability check, not
// CardTile). Either state confirms the modal mounted correctly.
await expect(
dialog.getByRole("button", { name: /^(Buy|Insufficient credits)$/ }),
).toBeVisible();

await dialog.getByRole("button", { name: /^Cancel$/ }).click();
await expect(dialog).toBeHidden();
Expand Down
41 changes: 8 additions & 33 deletions example-apps/dashnote-starter/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example-apps/dashnote-starter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"preview": "vite preview"
},
"dependencies": {
"@dashevo/evo-sdk": "4.0.0-rc.1",
"@dashevo/evo-sdk": "4.0.0-rc.2",
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
Expand Down
39 changes: 8 additions & 31 deletions example-apps/dashnote/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example-apps/dashnote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"preview": "vite preview"
},
"dependencies": {
"@dashevo/evo-sdk": "4.0.0-rc.1",
"@dashevo/evo-sdk": "4.0.0-rc.2",
"@tailwindcss/vite": "^4.2.2",
"react": "^19.2.4",
"react-dom": "^19.2.4",
Expand Down
2 changes: 1 addition & 1 deletion example-apps/dashnote/public/dashnote-lite.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ <h2>Get note by ID</h2>
// package and serves it as a browser-native ES module. Pinned to the same
// version the React app at ../package.json depends on so both UIs behave
// identically against the same testnet contract.
import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@3.1.0-dev.1';
import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@4.0.0-rc.2';

// The "note" data contract is already published on testnet by the React app.
// Anyone querying with the same contract id hits the same documents.
Expand Down
15 changes: 14 additions & 1 deletion example-apps/dashnote/test/e2e/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ export async function returnToList(page: Page) {
if (!isMobile(page)) return;
const back = page.getByRole("button", { name: /back to notes/i });
if (await back.isVisible().catch(() => false)) {
// A lingering sonner success toast (e.g. "Note saved") renders above the
// header and intercepts pointer events on "Back to notes". Best-effort
// wait for it to auto-dismiss before clicking; don't fail cleanup if it
// outlives the wait.
await waitForToastsToClear(page).catch(() => {});
await back.click();
}
// List view shows the Search input; wait for it to render.
Expand Down Expand Up @@ -242,7 +247,14 @@ export async function waitForSaveComplete(page: Page) {
return;
}

await expect(page.getByRole("button", { name: /^save$/i })).toBeDisabled({
// The button reads "Create note" while the editor still has selectedId ===
// "new" and only flips to "Save" once the post-create reload re-selects the
// note by its real id — which can lag behind testnet eventual consistency.
// Either way the editor is clean once the button is disabled (dirty=false),
// so match both labels rather than waiting on the id flip.
await expect(
page.getByRole("button", { name: /^(save|create note)$/i }),
).toBeDisabled({
timeout: 60_000,
});
}
Expand Down Expand Up @@ -305,6 +317,7 @@ export async function deleteNoteByTitle(page: Page, title: string) {
await expect(confirmDialog).toBeVisible();
await waitForToastsToClear(page);
await confirmDialog.getByRole("button", { name: /^delete$/i }).click();
await expect(confirmDialog).toBeHidden({ timeout: 60_000 });

// Item leaves the list after reloadNotes resolves.
await expect(page.locator("button", { hasText: title })).toHaveCount(0, {
Expand Down
25 changes: 15 additions & 10 deletions example-apps/dashnote/test/e2e/notes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,23 +228,28 @@ test("mobile: editor note actions delete flow opens confirmation", async ({
);

await returnToList(page);
await expect(
page.locator("button", { hasText: SEARCH_FIXTURE_BETA }).first(),
).toBeVisible({ timeout: 60_000 });
await page
.locator("button", { hasText: SEARCH_FIXTURE_BETA })
// This test only verifies the actions → Delete → confirm-dialog flow, so it
// doesn't matter which note is opened — open whichever the list shows first.
// Scope to a note-row container so the row's "Open {title}" button can't
// collide with the sidebar's "Open menu" hamburger.
const firstNote = page
.locator('[data-testid^="note-row-foreground-"]')
.first()
.click();
await expect(page.getByLabel("Title")).toHaveValue(SEARCH_FIXTURE_BETA);

await page.getByRole("button", { name: /note actions/i }).click();
.locator('[aria-label^="Open "]');
await expect(firstNote).toBeVisible({ timeout: 60_000 });
await firstNote.click();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
// Editor opened on a note: the actions trigger is only rendered when a
// note is selected.
const actionsTrigger = page.getByRole("button", { name: /note actions/i });
await expect(actionsTrigger).toBeVisible();

await actionsTrigger.click();
const actions = page.getByRole("dialog", { name: /note actions/i });
await expect(actions).toBeVisible();
await actions.getByRole("button", { name: /^delete$/i }).click();

const confirmDialog = page.getByRole("dialog", { name: /delete note/i });
await expect(confirmDialog).toBeVisible();
await expect(confirmDialog.getByText(SEARCH_FIXTURE_BETA)).toBeVisible();
await confirmDialog.getByRole("button", { name: /^cancel$/i }).click();
await expect(confirmDialog).toBeHidden();
});
Expand Down
Loading
Loading