diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 00000000..bd6a1f89 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,7 @@ +import {defineConfig} from "cypress" + +export default defineConfig({ + e2e: { + baseUrl: "http://localhost:5173", + }, +}) diff --git a/cypress/e2e/feed.cy.ts b/cypress/e2e/feed.cy.ts new file mode 100644 index 00000000..1c42494e --- /dev/null +++ b/cypress/e2e/feed.cy.ts @@ -0,0 +1,21 @@ +describe("feed interaction", () => { + beforeEach(() => { + cy.visit("/") + }) + + it("clicking a card works", () => { + cy.get(".cy-note-click-target:first").click() + cy.get(".modal .fa-heart") + cy.get(".modal .cy-modal-close").click() + + cy.get(".modal").should("not.exist") + }) + + it("feed controls works", () => { + cy.get(".fa-sliders").click() + cy.get(".modal .cy-chip:first .fa-times").click() + cy.get(".modal").contains("Apply Filters").click() + cy.contains("Kinds 30023,") + cy.get(".card", {timeout: 30000}) + }) +}) diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts new file mode 100644 index 00000000..d06b238b --- /dev/null +++ b/cypress/e2e/login.cy.ts @@ -0,0 +1,12 @@ +describe("authenticated usage", () => { + beforeEach(() => { + cy.login() + }) + + it("works", () => { + cy.visit("/") + cy.get("svg.logo").click() + cy.get(".card").contains("Profile").click() + cy.get(".cy-person-name").contains("test account 12938740") + }) +}) diff --git a/cypress/e2e/search.cy.ts b/cypress/e2e/search.cy.ts new file mode 100644 index 00000000..63f4baf9 --- /dev/null +++ b/cypress/e2e/search.cy.ts @@ -0,0 +1,10 @@ +describe("search", () => { + it("works", () => { + cy.visit("/") + cy.get(".cy-top-nav .fa-search").click() + cy.get(".cy-top-nav input").type("hodlbod") + cy.get(".modal").contains("hodlbod").click() + cy.get(".modal").contains("following") + cy.get(".modal").contains("followers") + }) +}) diff --git a/cypress/e2e/signup.cy.ts b/cypress/e2e/signup.cy.ts new file mode 100644 index 00000000..0f986b14 --- /dev/null +++ b/cypress/e2e/signup.cy.ts @@ -0,0 +1,23 @@ +describe("signup", () => { + beforeEach(() => { + cy.visit("/") + }) + + it("works", () => { + cy.get(".cy-top-nav").contains("Log In").click() + cy.get(".modal").contains("Sign Up").click() + cy.get(".modal").contains("Let's go!").click() + cy.get(".modal [name=name]").type("9sd2j3e0sd") + cy.get(".modal").contains("Continue").click() + cy.get(".modal").contains("Got it").click() + cy.get(".modal").contains("Continue").click() + cy.get(".modal").contains("Continue").click() + cy.wait(1000) + cy.get(".modal").contains("Skip and see your feed").click() + cy.get(".modal").should("not.exist") + cy.contains("From follows") + cy.get("svg.logo").click() + cy.get(".card").contains("Profile").click() + cy.get(".cy-person-name").contains("9sd2j3e0sd") + }) +}) diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 00000000..02e42543 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts new file mode 100644 index 00000000..ebce3985 --- /dev/null +++ b/cypress/support/commands.ts @@ -0,0 +1,29 @@ +const nsec = "nsec1er8narhat3xjypf46pksxlr6k4jrmv2e9psazjk0adynly0l4ltsepvmy5" + +Cypress.Commands.add("login", () => { + cy.session( + nsec, + () => { + cy.visit("/login/privkey") + cy.get("input[type=password]").type(nsec, {log: false}) + cy.get(".cy-login-submit").click() + cy.get(".modal", {timeout: 10_000}).should("not.exist") + cy.contains("Don't have an account?").should("not.exist") + }, + { + validate: () => { + let pubkey + + cy.window() + .then(w => { + pubkey = w.pubkey.get() + }) + .then(() => { + expect(pubkey).to.equal( + "c853d879b7376dab1cdcd4faf235a05f680aae42ba620abdd95d619542a5a379" + ) + }) + }, + } + ) +}) diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 00000000..b6eca754 --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import "./commands" + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/package.json b/package.json index ea0dd24a..ecff5dac 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@typescript-eslint/eslint-plugin": "^5.50.0", "@typescript-eslint/parser": "^5.50.0", "autoprefixer": "^10.4.13", + "cypress": "^13.3.1", "eslint": "^8.33.0", "eslint-plugin-svelte3": "^4.0.0", "postcss": "^8.4.19", @@ -55,6 +56,7 @@ "insane": "^2.6.2", "lru-cache": "^7.18.3", "marked": "^5.1.0", + "normalize-url": "^8.0.0", "nostr-tools": "^1.12.1", "npm-run-all": "^4.1.5", "paravel": "^0.3.7", diff --git a/src/app/App.svelte b/src/app/App.svelte index 7bd8ea01..feaab7ff 100644 --- a/src/app/App.svelte +++ b/src/app/App.svelte @@ -2,7 +2,7 @@ import "@fortawesome/fontawesome-free/css/fontawesome.css" import "@fortawesome/fontawesome-free/css/solid.css" - import {nip19} from "nostr-tools" + import {nip19, getPublicKey, generatePrivateKey} from "nostr-tools" import {pluck} from "ramda" import {seconds, Fetch} from "hurdak" import {tryFetch, hexToBech32, bech32ToHex, now} from "src/util/misc" @@ -223,7 +223,15 @@ // Globals - Object.assign(window, {...engine, nip19, bech32ToHex, hexToBech32, router}) + Object.assign(window, { + ...engine, + nip19, + bech32ToHex, + hexToBech32, + router, + getPublicKey, + generatePrivateKey, + }) // Theme diff --git a/src/app/TopNav.svelte b/src/app/TopNav.svelte index b5ae06ec..8d03a283 100644 --- a/src/app/TopNav.svelte +++ b/src/app/TopNav.svelte @@ -156,8 +156,8 @@ }} />
- You have muted this note.
+ You have hidden this note.
- You have muted this note.
+ You have hidden this note.
Currently searching:
diff --git a/src/app/views/Onboarding.svelte b/src/app/views/Onboarding.svelte
index 49114ca4..345aba07 100644
--- a/src/app/views/Onboarding.svelte
+++ b/src/app/views/Onboarding.svelte
@@ -1,8 +1,9 @@
-
- To get you started, we’ve added some interesting people to your follow list. You can update
- your follows list at any time.
-
+ To get you started, we’ve added some interesting people to your follow list. You can update your
+ follows list at any time.
+
- New to Nostr? Click
- When you’re ready to dive in, click below and we’ll guide you through the process of creating an
- account.
-
+ New to Nostr? Click
+ When you’re ready to dive in, click below and we’ll guide you through the process of creating an
+ account.
+
- Your private key is your password, and gives you total control over your Nostr account. We've
- generated a fresh one for you below – store it somewhere safe!
- If you don't want to save your keys now, you can find them later in {appName}'s settings.
+ Your private key is your password, and gives you total control over your Nostr account. We've
+ generated a fresh one for you below – store it somewhere safe!
+ If you don't want to save your keys now, you can find them later in {appName}'s settings.
- Your're all set! If have any questions, just ask! People around these parts are always ready to
- lend a hand.
-
+ Your're all set! If have any questions, just ask! People around these parts are always ready to
+ lend a hand.
+
- Give other people something to go on. Remember that "privacy is the power to selectively reveal
- oneself to the world".
- Please be mindful of others and only use small images.
+ Give other people something to go on. Remember that "privacy is the power to selectively reveal
+ oneself to the world".
+
- Nostr is a protocol, not a platform. This means that you choose where to store your data.
- Select your preferred storage relays below, or click "continue" to use some reasonable defaults.
- You can change your selection any time.
-
+ Nostr is a protocol, not a platform. This means that you choose where to store your data.
+
+ Select your preferred storage relays below, or click "continue" to use some reasonable defaults.
+ You can change your selection any time.
+Your follows
+Your follows
+Other people
- Other people
+Your relays
+Your relays
- Other relays
- Other relays
+