diff --git a/playwright-tests/tests/community.spec.js b/playwright-tests/tests/community.spec.js index 4b61a9e82..078c4a12d 100644 --- a/playwright-tests/tests/community.spec.js +++ b/playwright-tests/tests/community.spec.js @@ -33,6 +33,74 @@ test("should load an error page if handle does not exist", async ({ page }) => { expect(communityNotFound).not.toBeNull(); }); +test.describe("Wallet is connected", () => { + test.use({ + storageState: "playwright-tests/storage-states/wallet-connected.json", + }); + + test("should allow connected user to post from community page", async ({ + page, + }) => { + await page.goto( + "/devhub.near/widget/app?page=community&handle=devhub-test&tab=activity" + ); + + const postButtonSelector = 'a:has-text("Post")'; + + await page.waitForSelector(postButtonSelector, { + state: "visible", + }); + + // Click the Post button and wait for the load state to be 'networkidle' + await Promise.all([ + page.click(postButtonSelector), + page.waitForLoadState("networkidle"), + ]); + + // Verify that the URL is the expected one. + expect(page.url()).toBe( + "http://localhost:8080/devhub.near/widget/app?page=create&labels=devhub-test" + ); + + // Wait for the Typeahead field to render. + const typeaheadSelector = ".rbt-input-main"; + await page.waitForSelector(typeaheadSelector, { state: "visible" }); + + const typeaheadValueSelector = ".rbt-token-label"; + + // Wait for prepoluated label to appear. + await page.waitForSelector(typeaheadValueSelector, { state: "visible" }); + + // Fetch the element and its text content. + const element = await page.$(typeaheadValueSelector); + const elementText = await element.textContent(); + + expect(element).toBeTruthy(); + expect(elementText).toBe("devhub-test"); + }); +}); + +test.describe("Wallet is not connected", () => { + test.use({ + storageState: "playwright-tests/storage-states/wallet-not-connected.json", + }); + + test("should not allow unconnected user to post from community page", async ({ + page, + }) => { + await page.goto( + "/devhub.near/widget/app?page=community&handle=devhub-test" + ); + + const createCommunityButtonSelector = 'button:has-text("Post")'; + + await page.waitForSelector(createCommunityButtonSelector, { + state: "detached", + }); + }); +}); + + test.describe("Is community admin", () => { test.use({ storageState: diff --git a/src/devhub/entity/community/Activity.jsx b/src/devhub/entity/community/Activity.jsx new file mode 100644 index 000000000..47e42c8fb --- /dev/null +++ b/src/devhub/entity/community/Activity.jsx @@ -0,0 +1,79 @@ +const { handle } = props; + +const { getCommunity } = VM.require( + "${REPL_DEVHUB}/widget/core.adapter.devhub-contract" +); + +const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url"); + +if (!getCommunity || !href) { + return

Loading modules...

; +} + +// TODO: Why do we need to get community data again? Isn't the tag the handle... +const communityData = getCommunity({ handle }); + +if (communityData === null) { + return
Loading...
; +} + +const MainContent = styled.div` + flex-grow: 1; + max-width: 75%; + + @media screen and (max-width: 960px) { + max-width: 100%; + } +`; + +const SidebarContainer = styled.div` + max-width: 25%; + margin-right: 1.5rem; + + @media screen and (max-width: 960px) { + display: none; + } +`; + +return ( +
+
+
+ + + ), + recency, + transactionHashes: props.transactionHashes, + }} + /> + + + + +
+
+
+); \ No newline at end of file diff --git a/src/devhub/page/community/index.jsx b/src/devhub/page/community/index.jsx index 4b75b2661..ed017df7e 100644 --- a/src/devhub/page/community/index.jsx +++ b/src/devhub/page/community/index.jsx @@ -62,6 +62,13 @@ const tabs = [ handle: community.handle, }, }, + { + title: "Activity", + view: "${REPL_DEVHUB}/widget/devhub.entity.community.Activity", + params: { + handle: community.handle, + }, + }, { title: "Teams", view: "${REPL_DEVHUB}/widget/devhub.entity.community.Teams",