Skip to content

Commit

Permalink
Fix project creation w/ tests (#402)
Browse files Browse the repository at this point in the history
* init tests

* fmt

* rename test

* fmt

* clean test

* formatting

* working as-is test

* fmt

* fix upload image

* fmt

* complete editor tests

* projects tests

* fmt

* remove unused
  • Loading branch information
elliotBraem authored Jun 19, 2024
1 parent 3785d2f commit 588dab3
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 49 deletions.
29 changes: 21 additions & 8 deletions apps/new/widget/page/projects/Editor.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
const accountId = context.accountId;

if (!context.accountId) {
return (
<Widget
src="${config_account}/widget/components.LoginAction"
loading=""
props={{
text: "Please log in in order to see create or edit a project.",
}}
/>
);
}

const { Button, InputField, TextEditor, Modal } = VM.require(
"${alias_old}/widget/components",
) || {
Expand Down Expand Up @@ -661,7 +674,7 @@ const SecondScreen = () => {
src="${alias_old}/widget/components.UploadField"
props={{
image: avatar,
onChange: (image) => setAvatar({ image }),
onChange: (image) => setAvatar(image),
}}
/>
</div>
Expand All @@ -671,7 +684,7 @@ const SecondScreen = () => {
src="${alias_old}/widget/components.UploadField"
props={{
image: coverImage,
onChange: (image) => setCoverImage({ image }),
onChange: (image) => setCoverImage(image),
}}
/>
</div>
Expand Down Expand Up @@ -723,7 +736,11 @@ const SecondScreen = () => {
Back
</Button>

<Button variant="primary" onClick={onCreateProject}>
<Button
variant="primary"
onClick={onCreateProject}
disabled={invalidContributorFound}
>
{isEditScreen ? "Save Changes" : "Create"}
</Button>
</div>
Expand Down Expand Up @@ -880,11 +897,7 @@ const FirstScreen = () => {
<Button
variant="primary"
disabled={
invalidContributorFound ||
invalidProjectAccount ||
!title ||
!description ||
!projectAccount
invalidProjectAccount || !title || !description || !projectAccount
}
onClick={() => setCurrentScreen(2)}
>
Expand Down
5 changes: 4 additions & 1 deletion apps/new/widget/page/projects/ImportAndCreateModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ return (
onOpenChange={toggleModal}
toggle={toggle}
>
<Container className="d-flex flex-column gap-4 my-2">
<Container
className="d-flex flex-column gap-4 my-2"
data-testid="create-project-modal"
>
<Item
title="Create my own project"
description="Create your own completely new project, customize it your way!"
Expand Down
3 changes: 2 additions & 1 deletion apps/old/widget/components/InputField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ function InputField({
key={`input-container-${key}`}
style={{ maxWidth: maxWidth ?? "390px" }}
>
{label && <Label>{label}</Label>}
{label && <Label htmlFor={label}>{label}</Label>}
<InputWrapper style={{ maxWidth: maxWidth ?? "390px" }}>
{prefix && <PrefixContainer>{prefix}</PrefixContainer>}
<Input
id={label}
key={`input-field-${key}`}
value={value}
className={error ? "invalid" : ""}
Expand Down
8 changes: 5 additions & 3 deletions apps/old/widget/components/UploadField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const uploadFile = (files) => {
})
.then((res) => {
setImg(res.body.cid);
props.setImage({
ipfs_cid: res.body.cid,
});
if (props.onChange) {
props.onChange({
ipfs_cid: res.body.cid,
});
}
});
};

Expand Down
12 changes: 5 additions & 7 deletions playwright-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,15 @@ It is encouraged to include video in pull requests in order to demonstrate funct
Currently, none of the tests post actual transactions to the smart contracts. Still you should try writing your tests so that they do the actual function call, but just skip the final step of sending the transaction. You can do this by capturing the transaction confirmation popup provided by the NEAR social VM.

```javascript
const expectedTransactionData = {};

// click button that triggers transaction
await page.getByRole("button", { name: "Donate" }).nth(1).click();
await page.getByRole("button", { name: "Create" }).nth(1).click();

const transactionObj = JSON.parse(await page.locator("div.modal-body code").innerText());

// do something with transactionObj
expect(transactionObj).toMatchObject({
amount: 100,
message: "",
projectId: DEFAULT_PROJECT_ID,
});
expect(transactionObj).toMatchObject(expectedTransactionData);
```

See the test called "project with no active pot should donate direct with correct amount" in donate.spec.js for a full example.
See the test called "should complete flow and save data correctly with images populated" in editor.spec.js for a full example.
Binary file added playwright-tests/tests/assets/black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
232 changes: 232 additions & 0 deletions playwright-tests/tests/editor.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import { expect, test } from "@playwright/test";
import path from "path";
import { ROOT_SRC } from "../util/constants";

test.describe("?page=projects&tab=editor", () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/${ROOT_SRC}?page=projects&tab=editor`);
});

test.describe("User is not logged in", () => {
test.use({
storageState: "playwright-tests/storage-states/wallet-not-connected.json",
});

test("editor page should prompt user to log in", async ({ page }) => {
const requireLogin = await page.getByText(
"Please log in in order to see create or edit a project.",
);

await expect(requireLogin).toBeVisible();
});
});

test.describe("User is logged in", () => {
test.use({
storageState: "playwright-tests/storage-states/wallet-connected.json",
});

test.beforeEach(async ({ page }) => {
// Intercept IPFS requests
await page.route("**/add", async (route) => {
const modifiedResponse = {
status: 200,
contentType: "application/json",
body: JSON.stringify({ cid: "simple_cid" }),
};

// Fulfill the route with the modified response
await route.fulfill(modifiedResponse);
});
});

test("should not allow next when empty required fields", async ({
page,
}) => {
const nextButton = await page.getByRole("button", { name: "Next" });
await expect(nextButton).toBeDisabled();

const projectAccountAddress = await page.getByPlaceholder(
"Enter Project Account Address",
);

const title = await page.getByPlaceholder("Enter Project Title");
const description = await page
.frameLocator("iframe")
.locator('textarea[name="textarea"]');

// Fill required fields
await projectAccountAddress.fill("anyproject.near");
await title.fill("Sample project");

await description.click();
await description.fill("This is a sample project");

await expect(nextButton).toBeEnabled();

// Clear title
await title.clear();
await expect(nextButton).toBeDisabled();

await title.fill("Sample project");
await expect(nextButton).toBeEnabled();

await description.click();
await description.clear();
await expect(nextButton).toBeDisabled();
});

test("should not allow invalid project account address", async ({
page,
}) => {
// Project Account Address
await page
.getByPlaceholder("Enter Project Account Address")
.fill("anyproject");

const errorMsg = await page.getByText(
"Invalid Near Address, please enter a valid near address",
);
await expect(errorMsg).toBeVisible();
});

test("cancel should navigate to main projects page", async ({ page }) => {
await page.getByRole("button", { name: "Cancel" }).click();
expect(page.url()).toContain("?page=projects");
});

test("should complete flow and save data correctly with images populated", async ({
page,
}) => {
const expectedProjectData = {
// TODO: We will want to get rid of this
title: "Sample project",
description: "This is a sample project",
profileImage: {
ipfs_cid: "simple_cid",
},
backgroundImage: {
ipfs_cid: "simple_cid",
},
tags: {
test: "",
},
linktree: {
twitter: "SampleTwitter",
github: "SampleGithub",
telegram: "SampleTelegram",
website: "https://www.samplewebsite.com",
},
// End remove
contributors: ["anybody.near", "nobody.near"],
tabs: ["overview", "tasks", "activity"],
projectAccountId: "anyproject.near",
teamSize: "1-10",
location: "anywhere",
};

const expectedTransactionData = {
"anybody.near": {
project: {
"sample-project": {
"": JSON.stringify(expectedProjectData),
metadata: {
name: "Sample project",
description: "This is a sample project",
image: {
ipfs_cid: "simple_cid",
},
backgroundImage: {
ipfs_cid: "simple_cid",
},
tags: {
test: "",
},
linktree: {
github: "https://github.com/SampleGithub",
telegram: "https://t.me/SampleTelegram",
twitter: "https://twitter.com/SampleTwitter",
website: "https://www.samplewebsite.com",
},
},
},
},
"builddao.testnet": {
project: {
"anybody.near_project_sample-project": "",
},
},
},
};

// Page one //

// Project Account Address
await page
.getByPlaceholder("Enter Project Account Address")
.fill("anyproject.near");

// Title
await page.getByPlaceholder("Enter Project Title").fill("Sample project");

// Description
await page
.frameLocator("iframe")
.locator('textarea[name="textarea"]')
.click();
await page
.frameLocator("iframe")
.locator('textarea[name="textarea"]')
.fill("This is a sample project");

await page.getByPlaceholder("Enter location").fill("anywhere"); // Location

await page.getByRole("combobox").selectOption("1-10");

await page.getByLabel("Twitter").fill("SampleTwitter");
await page.getByLabel("Github").fill("SampleGithub");
await page.getByLabel("Telegram").fill("SampleTelegram");
await page.getByLabel("Website").fill("https://www.samplewebsite.com");

// Next page
await page.getByRole("button", { name: "Next" }).click();

// Page two //

// Contributors
await page.getByRole("combobox").nth(0).click();
await page.getByRole("combobox").nth(0).fill("nobody.near");
await page.getByLabel("nobody.near").click();

// Avatar
const avatarInput = await page.locator("input[type=file]").nth(0);
await avatarInput.setInputFiles(
path.join(__dirname, "./assets/black.png"),
);

// Background
const backgroundInput = await page.locator("input[type=file]").nth(1);
await backgroundInput.setInputFiles(
path.join(__dirname, "./assets/black.png"),
);

await page.getByLabel("Updates Feed").uncheck();
await page.getByLabel("Feedback Feed").uncheck();

await page.getByRole("combobox").nth(1).click();
await page.getByRole("combobox").nth(1).fill("test");
await page.getByLabel("test").click();

await page.getByRole("button", { name: "Create" }).click();
await page.getByRole("dialog").getByLabel("Close").click();

// click button that triggers transaction
await page.getByRole("button", { name: "Create" }).nth(0).click();
const transactionObj = JSON.parse(
await page.locator("div.modal-body code").innerText(),
);
// do something with transactionObj
expect(transactionObj).toMatchObject(expectedTransactionData);
});
});
});
Loading

0 comments on commit 588dab3

Please sign in to comment.