Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
38 changes: 20 additions & 18 deletions cypress/e2e/code-block-with-copy.cy.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use strict";

const visitWithClipboardSpy = (url) => {
// Load page with a controllable clipboard implementation for this test run.
cy.visit(url, {
onBeforeLoad(win) {
Object.defineProperty(win, "isSecureContext", {
Expand All @@ -18,7 +17,6 @@ const visitWithClipboardSpy = (url) => {
},
});

// Stub clipboard writes so tests can assert exact copied text.
cy.window().then((win) => {
cy.stub(win.navigator.clipboard, "writeText")
.as("clipboardWriteText")
Expand All @@ -27,26 +25,29 @@ const visitWithClipboardSpy = (url) => {
};

const getFirstWebpackConfigBlock = (aliasName) => {
cy.contains("strong", "webpack.config.js")
cy.get(".group")
.filter((i, el) => el.querySelector("code"))
.first()
.parent()
.next(".code-block-wrapper")
.as(aliasName);
};

describe("CodeBlockWithCopy", () => {
it("copies diff code blocks without removed lines or diff prefixes", () => {
visitWithClipboardSpy("/guides/output-management/");

// Select the first webpack.config.js diff example and its copy wrapper.
cy.contains("h1", "Output Management", { timeout: 10000 }).should("exist");

getFirstWebpackConfigBlock("diffCodeBlock");

// Trigger copy for that specific diff code block.
cy.get("@diffCodeBlock").find("code.language-diff").should("exist");
cy.get("@diffCodeBlock").find("button.copy-button").click();
cy.get("@diffCodeBlock").find("code").should("exist");

cy.get("@diffCodeBlock")
.find('button[aria-label="Copy code to clipboard"]')
.should("exist")
.click();

// Assert copied output strips diff markers and removed lines.
cy.get("@clipboardWriteText").should("have.been.calledOnce");

cy.get("@clipboardWriteText").then((clipboardWriteText) => {
const [copiedText] = clipboardWriteText.getCall(0).args;

Expand All @@ -64,23 +65,24 @@ describe("CodeBlockWithCopy", () => {
it("copies non-diff code blocks without altering content", () => {
visitWithClipboardSpy("/concepts/");

// Wait for Suspense content to load before querying code blocks
cy.get("button.copy-button").should("exist");
cy.contains("h1", "Concepts", { timeout: 10000 }).should("exist");

// Select the first webpack.config.js example and its copy wrapper.
getFirstWebpackConfigBlock("standardCodeBlock");

// Capture the rendered source text and trigger copy from this non-diff snippet.
cy.get("@standardCodeBlock").find("code.language-diff").should("not.exist");
cy.get("@standardCodeBlock").find("code").should("exist");

cy.get("@standardCodeBlock")
.find("code")
.invoke("text")
.as("expectedCopiedText");
cy.get("@standardCodeBlock").find("button.copy-button").should("exist");
cy.get("@standardCodeBlock").find("button.copy-button").click();

// Assert copied output is unchanged for regular code blocks.
cy.get("@standardCodeBlock")
.find('button[aria-label="Copy code to clipboard"]')
.should("exist")
.click();

cy.get("@clipboardWriteText").should("have.been.calledOnce");

cy.get("@clipboardWriteText").then((clipboardWriteText) => {
const [copiedText] = clipboardWriteText.getCall(0).args;

Expand Down
14 changes: 11 additions & 3 deletions src/components/CodeBlockWithCopy/CodeBlockWithCopy.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from "prop-types";
import { useEffect, useRef, useState } from "react";
import "./CodeBlockWithCopy.scss";
// Tailwind CSS is now used for styling. Custom SCSS removed.

export default function CodeBlockWithCopy({ children }) {
const preRef = useRef(null);
Expand Down Expand Up @@ -115,11 +115,19 @@ export default function CodeBlockWithCopy({ children }) {
);

return (
<div className="code-block-wrapper">
<div className="relative mb-6 group">
<button
onClick={handleCopy}
className={`copy-button ${copyStatus}`}
aria-label="Copy code to clipboard"
className={`absolute top-2 right-2 z-10 px-3 py-1.5 rounded-md border-none cursor-pointer text-xs font-medium opacity-0 group-hover:opacity-100 focus-visible:opacity-100 transition-all duration-300
${
copyStatus === "copied"
? "bg-green-600 hover:bg-green-700 text-gray-100"
: copyStatus === "error"
? "bg-red-600 hover:bg-red-700 text-gray-100"
: "bg-blue-700 hover:bg-blue-600 text-blue-100"
}
active:scale-95 focus:outline-none`}
>
{copyStatus === "copied"
? "Copied!"
Expand Down
66 changes: 0 additions & 66 deletions src/components/CodeBlockWithCopy/CodeBlockWithCopy.scss

This file was deleted.

Loading
Loading