diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index d3538e6..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1 +0,0 @@
-cypress
diff --git a/cypress/.eslintrc.js b/cypress/.eslintrc.js
new file mode 100644
index 0000000..37c79ff
--- /dev/null
+++ b/cypress/.eslintrc.js
@@ -0,0 +1,6 @@
+module.exports = {
+ parserOptions: {
+ tsconfigRootDir: __dirname,
+ project: "./tsconfig.json",
+ },
+};
diff --git a/cypress/consts/urlRegexes.js b/cypress/consts/urlRegexes.ts
similarity index 100%
rename from cypress/consts/urlRegexes.js
rename to cypress/consts/urlRegexes.ts
diff --git a/cypress/integration/about/about.spec.ts b/cypress/integration/about/about.spec.ts
new file mode 100644
index 0000000..d77206b
--- /dev/null
+++ b/cypress/integration/about/about.spec.ts
@@ -0,0 +1,11 @@
+describe("About", () => {
+ it("should not have broken links", () => {
+ cy.visit(`${Cypress.env("hostUrl")}/sobre`);
+
+ cy.getByDataTest("accordion-container").within(() => {
+ cy.findAllByRole("link").each((link) => {
+ cy.request(link.prop("href")).its("status").should("eq", 200);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/header/header.spec.js b/cypress/integration/header/header.spec.js
deleted file mode 100644
index e99ae33..0000000
--- a/cypress/integration/header/header.spec.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { streamsRegex, tagsRegex, vodsRegex } from "../../consts/urlRegexes";
-
-describe("Home > Filter", () => {
- it("should have correct links", () => {
- const LINKS = [
- { text: "Assistir", href: "/" },
- { text: "Sobre", href: "/sobre" },
- { text: "Estatísticas", href: "/estatisticas" },
- { text: "Agradecimentos", href: "/agradecimentos" },
- { text: "GitHub", href: "https://github.com/brdevstreamers" },
- { text: "Discord", href: "https://discord.gg/collabcode" },
- ];
-
- cy.visit(Cypress.env("hostUrl"));
-
- cy.getByData("header-link").should("have.length", LINKS.length);
-
- LINKS.forEach(({ text, href }) => {
- cy.getByData("header-link").contains(text).should("have.attr", "href", href);
- });
- });
-});
diff --git a/cypress/integration/header/header.spec.ts b/cypress/integration/header/header.spec.ts
new file mode 100644
index 0000000..8893c4c
--- /dev/null
+++ b/cypress/integration/header/header.spec.ts
@@ -0,0 +1,11 @@
+describe("Header", () => {
+ it("should not have broken links", () => {
+ cy.visit(Cypress.env("hostUrl"));
+
+ cy.getByDataTest("header-container").within(() => {
+ cy.findAllByRole("link").each((link) => {
+ cy.request(link.prop("href")).its("status").should("eq", 200);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/home/filter.spec.js b/cypress/integration/home/filter.spec.js
deleted file mode 100644
index 60e26b0..0000000
--- a/cypress/integration/home/filter.spec.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import { streamsRegex, tagsRegex, vodsRegex } from "../../consts/urlRegexes";
-
-describe("Home > Filter", () => {
- beforeEach(() => {
- cy.intercept(streamsRegex, {
- statusCode: 200,
- fixture: "streams",
- }).as("streams");
- cy.intercept(tagsRegex, {
- statusCode: 200,
- fixture: "tags",
- }).as("tags");
- cy.intercept(vodsRegex, {
- statusCode: 200,
- fixture: "vods",
- }).as("vods");
- });
-
- it("should filter out streams by tags change the URL", () => {
- const PROGRAMMING_TEXT = "Programação";
- const PROGRAMMING_TEXT_ENCODED = encodeURIComponent(PROGRAMMING_TEXT);
- const JAVASCRIPT_TEXT = "JavaScript";
- const LGBTQIA_TEXT = "LGBTQIA+";
- const LGBTQIA_TEXT_ENCODED = encodeURIComponent("LGBTQIA+");
-
- cy.visit(Cypress.env("hostUrl"));
- cy.wait(["@streams", "@tags", "@vods"]);
-
- cy.getByData("card-online").should("have.length", 13);
-
- cy.getByData("tag-filter-item-unselected")
- .contains(PROGRAMMING_TEXT)
- .should("have.prop", "tagName", "A")
- .should("have.attr", "href", `?tags=${PROGRAMMING_TEXT_ENCODED}`)
- .click();
- cy.getByData("card-online").should("have.length", 2);
-
- cy.url().should("contain", `?tags=${PROGRAMMING_TEXT_ENCODED}`);
-
- cy.getByData("tag-filter-item-selected").contains(PROGRAMMING_TEXT).click();
- cy.getByData("card-online").should("have.length", 13);
-
- cy.getByData("tag-filter-item-unselected").contains(PROGRAMMING_TEXT).click();
-
- cy.getByData("tag-filter-item-unselected")
- .contains(JAVASCRIPT_TEXT)
- .should("have.prop", "tagName", "A")
- .should("have.attr", "href", `?tags=${JAVASCRIPT_TEXT}`)
- .click();
-
- cy.url().should(
- "contain",
- `?tags=${encodeURIComponent(`${PROGRAMMING_TEXT},${JAVASCRIPT_TEXT}`)}`,
- );
-
- cy.getByData("card-online").should("have.length", 1);
-
- cy.getByData("tag-filter-item-unselected")
- .contains(LGBTQIA_TEXT)
- .should("have.prop", "tagName", "A")
- .should("have.attr", "href", `?tags=${LGBTQIA_TEXT_ENCODED}`)
- .click();
-
- cy.url().should(
- "contain",
- `?tags=${encodeURIComponent(`${PROGRAMMING_TEXT},${JAVASCRIPT_TEXT},${LGBTQIA_TEXT}`)}`,
- );
-
- cy.getByData("card-online").should("have.length", 0);
-
- cy.getByData("tag-filter-item-selected").contains(LGBTQIA_TEXT).click();
- cy.getByData("card-online").should("have.length", 1);
-
- cy.getByData("tag-filter-item-selected").contains(JAVASCRIPT_TEXT).click();
- cy.getByData("card-online").should("have.length", 2);
-
- cy.getByData("tag-filter-item-selected").contains(PROGRAMMING_TEXT).click();
- cy.getByData("card-online").should("have.length", 13);
- });
-
- it("should accept the tag query string to filter out streams", () => {
- const JAVASCRIPT_TEXT = "JavaScript";
-
- cy.visit(`http://localhost:3000/?tags=${JAVASCRIPT_TEXT}`);
- cy.wait(["@streams", "@tags", "@vods"]);
-
- cy.getByData("tag-filter-item-selected")
- .contains(JAVASCRIPT_TEXT)
- .should("have.css", "backgroundColor", "rgb(139, 61, 255)")
- .should("have.length", 1);
- cy.getByData("card-online").should("have.length", 3);
- });
-});
diff --git a/cypress/integration/home/filter.spec.ts b/cypress/integration/home/filter.spec.ts
new file mode 100644
index 0000000..ba1f21c
--- /dev/null
+++ b/cypress/integration/home/filter.spec.ts
@@ -0,0 +1,68 @@
+import { streamsRegex, tagsRegex, vodsRegex } from "../../consts/urlRegexes";
+
+describe("Home > Filter", () => {
+ beforeEach(() => {
+ cy.intercept(streamsRegex, {
+ statusCode: 200,
+ fixture: "streams",
+ }).as("streams");
+ cy.intercept(tagsRegex, {
+ statusCode: 200,
+ fixture: "tags",
+ }).as("tags");
+ cy.intercept(vodsRegex, {
+ statusCode: 200,
+ fixture: "vods",
+ }).as("vods");
+ });
+
+ it("should filter out streams by tags change the URL", () => {
+ const PROGRAMMING_TEXT = "Programação";
+ const JAVASCRIPT_TEXT = "JavaScript";
+ const LGBTQIA_TEXT = "LGBTQIA+";
+
+ cy.visit(Cypress.env("hostUrl"));
+ cy.wait(["@streams", "@tags", "@vods"]);
+
+ cy.getByDataTest("card-online").should("have.length", 13);
+
+ cy.filterByTag(PROGRAMMING_TEXT);
+ cy.shouldUrlContainTags(PROGRAMMING_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 2);
+
+ cy.unFilterByTag(PROGRAMMING_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 13);
+
+ cy.filterByTag(PROGRAMMING_TEXT);
+ cy.filterByTag(JAVASCRIPT_TEXT);
+ cy.shouldUrlContainTags(PROGRAMMING_TEXT, JAVASCRIPT_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 1);
+
+ cy.filterByTag(LGBTQIA_TEXT);
+ cy.shouldUrlContainTags(PROGRAMMING_TEXT, JAVASCRIPT_TEXT, LGBTQIA_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 0);
+
+ cy.unFilterByTag(LGBTQIA_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 1);
+
+ cy.unFilterByTag(JAVASCRIPT_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 2);
+
+ cy.unFilterByTag(PROGRAMMING_TEXT);
+ cy.getByDataTest("card-online").should("have.length", 13);
+ });
+
+ it("should accept the tag query string to filter out streams", () => {
+ const JAVASCRIPT_TEXT = "JavaScript";
+
+ cy.visit(`http://localhost:3000/?tags=${JAVASCRIPT_TEXT}`);
+ cy.wait(["@streams", "@tags", "@vods"]);
+
+ cy.getByDataTest("tag-filter")
+ .contains(JAVASCRIPT_TEXT)
+ .should("have.css", "backgroundColor", "rgb(139, 61, 255)")
+ .should("have.length", 1);
+
+ cy.getByDataTest("card-online").should("have.length", 3);
+ });
+});
diff --git a/cypress/integration/home/raid.spec.js b/cypress/integration/home/raid.spec.ts
similarity index 77%
rename from cypress/integration/home/raid.spec.js
rename to cypress/integration/home/raid.spec.ts
index 113a746..a3acf76 100644
--- a/cypress/integration/home/raid.spec.js
+++ b/cypress/integration/home/raid.spec.ts
@@ -1,7 +1,7 @@
import { streamsRegex, tagsRegex, vodsRegex } from "../../consts/urlRegexes";
describe("Home > Raid", () => {
- it("Copy raid command to clipboard", () => {
+ it("should copy raid command to clipboard", () => {
const COPIED_TEXT = "/raid emersongarrido";
cy.intercept(streamsRegex, {
@@ -41,11 +41,13 @@ describe("Home > Raid", () => {
cy.wait(["@streams", "@tags", "@vods"]);
- cy.getByData("raid-button").first().click();
- cy.window().its("navigator.clipboard").invoke("readText").should("equal", COPIED_TEXT);
+ cy.getByDataTest("card-online")
+ .first()
+ .within(() => {
+ cy.findByRole("button", { name: "Raid" }).click();
+ cy.window().its("navigator.clipboard").invoke("readText").should("equal", COPIED_TEXT);
+ });
- cy.get(".chakra-alert").within(() => {
- cy.get(".chakra-alert__title").contains(`Comando "${COPIED_TEXT}" copiado!`);
- });
+ cy.findByRole("alert", { name: `Comando "${COPIED_TEXT}" copiado!` }).should("have.length", 1);
});
});
diff --git a/cypress/integration/home/refetch.spec.js b/cypress/integration/home/refetch.spec.ts
similarity index 85%
rename from cypress/integration/home/refetch.spec.js
rename to cypress/integration/home/refetch.spec.ts
index 019ca8c..a110493 100644
--- a/cypress/integration/home/refetch.spec.js
+++ b/cypress/integration/home/refetch.spec.ts
@@ -18,7 +18,7 @@ describe("Home > Refetch", () => {
cy.visit(Cypress.env("hostUrl"));
cy.wait(["@streams", "@tags", "@vods"]);
- cy.getByData("card-online").should("have.length", 13);
+ cy.getByDataTest("card-online").should("have.length", 13);
cy.intercept(streamsRegex, {
statusCode: 200,
@@ -27,6 +27,6 @@ describe("Home > Refetch", () => {
cy.tick(120 * 1000)
cy.wait(["@streams", "@tags", "@vods"]);
- cy.getByData("card-online").should("have.length", 2);
+ cy.getByDataTest("card-online").should("have.length", 2);
});
-});
\ No newline at end of file
+});
diff --git a/cypress/integration/home/simultaneous.spec.js b/cypress/integration/home/simultaneous.spec.ts
similarity index 69%
rename from cypress/integration/home/simultaneous.spec.js
rename to cypress/integration/home/simultaneous.spec.ts
index a369449..b2f0b7c 100644
--- a/cypress/integration/home/simultaneous.spec.js
+++ b/cypress/integration/home/simultaneous.spec.ts
@@ -17,10 +17,12 @@ describe("Home > Simultaneous", () => {
cy.visit(Cypress.env("hostUrl"));
cy.wait(["@streams", "@tags", "@vods"]);
- cy.getByData("simultaneous-button").click();
- cy.getByData("start-simultaneous-button").click();
- cy.get(".chakra-toast")
- .should("have.length", 1)
- .contains("Você deve selecionar pelo menos duas streams");
+ cy.getByDataTest("simultaneous-button").click();
+ cy.getByDataTest("start-simultaneous-button").click();
+
+ cy.findByRole("alert", { name: "Você deve selecionar pelo menos duas streams" }).should(
+ "have.length",
+ 1,
+ );
});
});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
deleted file mode 100644
index 59b2bab..0000000
--- a/cypress/plugins/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-///
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-/**
- * @type {Cypress.PluginConfig}
- */
-// eslint-disable-next-line no-unused-vars
-module.exports = (on, config) => {
- // `on` is used to hook into various events Cypress emits
- // `config` is the resolved Cypress config
-}
diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts
new file mode 100644
index 0000000..94c9ceb
--- /dev/null
+++ b/cypress/plugins/index.ts
@@ -0,0 +1,10 @@
+module.exports = (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
+ on("task", {
+ log(message) {
+ console.log(message);
+ return null;
+ },
+ });
+
+ return config;
+};
diff --git a/cypress/support/@types/selectors.d.ts b/cypress/support/@types/selectors.d.ts
new file mode 100644
index 0000000..f159545
--- /dev/null
+++ b/cypress/support/@types/selectors.d.ts
@@ -0,0 +1,7 @@
+export type Selectors =
+| "accordion-container"
+| "card-online"
+| "header-container"
+| "simultaneous-button"
+| "start-simultaneous-button"
+| "tag-filter"
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
deleted file mode 100644
index 0f3e8e7..0000000
--- a/cypress/support/commands.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add('login', (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
-
-Cypress.on("uncaught:exception", () => false);
-
-Cypress.Commands.add("getByData", (selector, ...args) =>
- cy.get(`[data-test=${selector}]`, ...args),
-);
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
new file mode 100644
index 0000000..c6405b7
--- /dev/null
+++ b/cypress/support/commands.ts
@@ -0,0 +1,132 @@
+import type { Selectors } from "./@types/selectors";
+
+declare global {
+ namespace Cypress {
+ interface Chainable {
+ /**
+ * Custom command to get element by data-test attribute
+ * @param selector data-test attribute value
+ * @param options
+ * @example
+ * cy.getByDataTest('someDataTestValue')
+ */
+ getByDataTest: typeof getByDataTest;
+
+ /**
+ * Custom command to filter by tag name
+ * @param tag tag name to filter
+ * @example
+ * cy.filterByTag('JavaScript')
+ */
+ filterByTag: typeof filterByTag;
+
+ /**
+ * Custom command to unfilter by tag name
+ * @param tag tag name to unfilter
+ * @example
+ * cy.unFilterByTag('JavaScript')
+ */
+ unFilterByTag: typeof unFilterByTag;
+
+ /**
+ * Custom command to check if url contain specified tags
+ * @param tags tags to check in url
+ * @example
+ * cy.shouldUrlContainTags('JavaScript')
+ * cy.shouldUrlContainTags('JavaScript', 'LGBTQIA+')
+ */
+ shouldUrlContainTags: typeof shouldUrlContainTags;
+ }
+ }
+}
+
+const getByDataTest = (
+ selector: Selectors,
+ options?: Partial,
+) => {
+ const log = Cypress.log({
+ displayName: "getByDataTest",
+ name: "Get by [data-test] attribute",
+ });
+
+ cy.on("fail", (error) => {
+ log.error(error);
+ log.end();
+ throw error;
+ });
+
+ return cy.get(`[data-test=${selector}]`, options);
+};
+
+const filterByTag = (tag: string) => {
+ const encodedTag = encodeURIComponent(tag);
+
+ const log = Cypress.log({
+ autoEnd: false,
+ displayName: "filterByTag",
+ name: `Filtering by ${tag}`,
+ });
+
+ cy.on("fail", (error) => {
+ log.error(error);
+ log.end();
+ throw error;
+ });
+
+ return cy
+ .getByDataTest("tag-filter")
+ .contains(tag)
+ .then(($el) => {
+ log.set({ $el });
+ log.snapshot();
+ log.end();
+ })
+ .should("have.prop", "tagName", "A")
+ .should("have.attr", "href", `?tags=${encodedTag}`)
+ .click();
+};
+
+const unFilterByTag = (tag: string) => {
+ const log = Cypress.log({
+ autoEnd: false,
+ displayName: "unFilterByTag",
+ name: `Unfiltering by ${tag}`,
+ });
+
+ cy.on("fail", (error) => {
+ log.error(error);
+ log.end();
+ throw error;
+ });
+
+ return cy
+ .getByDataTest("tag-filter")
+ .contains(tag)
+ .then(($el) => {
+ log.set({ $el });
+ log.snapshot();
+ log.end();
+ })
+ .click();
+};
+
+const shouldUrlContainTags = (...tags: Array) => {
+ Cypress.log({
+ displayName: "shouldUrlContainTags",
+ name: `Check if Url contains ${tags.join(", ")}`,
+ });
+
+ cy.url().should("contain", `?tags=${encodeURIComponent(tags.join(","))}`);
+};
+
+Cypress.on("uncaught:exception", () => false);
+
+Cypress.Commands.add("getByDataTest", getByDataTest);
+Cypress.Commands.add("filterByTag", filterByTag);
+Cypress.Commands.add("unFilterByTag", unFilterByTag);
+Cypress.Commands.add("shouldUrlContainTags", shouldUrlContainTags);
+
+/*
+eslint
+ @typescript-eslint/no-namespace: "off",
+*/
diff --git a/cypress/support/index.js b/cypress/support/index.js
deleted file mode 100644
index d076cec..0000000
--- a/cypress/support/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// ***********************************************************
-// This example support/index.js 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/cypress/support/index.ts b/cypress/support/index.ts
new file mode 100644
index 0000000..4feab96
--- /dev/null
+++ b/cypress/support/index.ts
@@ -0,0 +1,2 @@
+import "@testing-library/cypress/add-commands";
+import "./commands";
diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json
new file mode 100644
index 0000000..fdc7cb2
--- /dev/null
+++ b/cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "exclude": ["../node_modules/@types/jest", "../node_modules/@testing-library/jest-dom"],
+ "include": ["integration/**/*", "plugins/**/*", "support/**/*"],
+ "compilerOptions": {
+ "baseUrl": ".",
+ "noEmit": true,
+ "types": ["node", "cypress", "@testing-library/cypress"],
+ "esModuleInterop": true,
+ "jsx": "react",
+ "moduleResolution": "node",
+ "target": "es2019",
+ "strict": true,
+ "skipLibCheck": true,
+ "resolveJsonModule": true,
+ "typeRoots": ["../node_modules/@types"]
+ }
+}
diff --git a/package.json b/package.json
index c19e178..f9ba83f 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
"devDependencies": {
"@commitlint/cli": "^16.2.1",
"@commitlint/config-conventional": "^16.2.1",
+ "@testing-library/cypress": "^8.0.2",
"@types/cypress": "^1.1.3",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
@@ -87,7 +88,6 @@
"lint-staged": ">=12",
"prettier": "^2.5.1"
},
-
"lint-staged": {
"src/**/*": [
"yarn lint --fix"
diff --git a/scripts/getSelectors.sh b/scripts/getSelectors.sh
new file mode 100755
index 0000000..5fdbb8f
--- /dev/null
+++ b/scripts/getSelectors.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+# Credits: https://github.com/filiphric/trelloapp-vue-vite-ts/blob/main/scripts/getSelectors.sh
+
+# find all data-test attribute in src | select values |
+SRC_SELECTORS=$(grep -hro 'data-test="[^"]*"' src | cut -d \" -f2 | sort | uniq)
+TEST_SELECTORS=$(grep -hro '.getByDataTest([^"]*' cypress | cut -d \' -f2 | sort | uniq)
+
+UNUSED_SELECTORS=$(comm -23 <(echo "$SRC_SELECTORS") <(echo "$TEST_SELECTORS"))
+
+if [[ $UNUSED_SELECTORS != "" ]]; then
+echo -e "WARNING! There are some selectors in your app that are not being used:
+
+
+$UNUSED_SELECTORS"
+fi
+
+echo $SRC_SELECTORS | sed "s/ /\"\n| \"/g; s/^/&export type Selectors = \n| \"/; s/.$/&\"/;" | cat > cypress/support/@types/selectors.d.ts
diff --git a/src/components/sections/Header.tsx b/src/components/sections/Header.tsx
index fd6ce22..f622291 100644
--- a/src/components/sections/Header.tsx
+++ b/src/components/sections/Header.tsx
@@ -52,7 +52,13 @@ export default function Header() {
return (
<>
-
+
@@ -77,7 +83,6 @@ export default function Header() {
color: "primary.500",
}}
_hover={{ textDecoration: "underline" }}
- data-test="header-link"
>
{link.label}
@@ -90,7 +95,6 @@ export default function Header() {
href={"https://github.com/brdevstreamers"}
color={"gray.100"}
_hover={{ textDecoration: "underline" }}
- data-test="header-link"
>
GitHub
@@ -99,7 +103,6 @@ export default function Header() {
href={"https://discord.gg/collabcode"}
color={"gray.100"}
_hover={{ textDecoration: "underline" }}
- data-test="header-link"
>
Discord
diff --git a/src/components/ui/Card.tsx b/src/components/ui/Card.tsx
index 104b926..51904fa 100644
--- a/src/components/ui/Card.tsx
+++ b/src/components/ui/Card.tsx
@@ -168,7 +168,6 @@ export default function Card({
{isLive && (