Skip to content

🧪 test: cover fallback copy DOM operations in useCopyToClipboard - #517

Open
is0692vs wants to merge 1 commit into
mainfrom
test/fallback-copy-useCopyToClipboard-17424069591778516712
Open

🧪 test: cover fallback copy DOM operations in useCopyToClipboard#517
is0692vs wants to merge 1 commit into
mainfrom
test/fallback-copy-useCopyToClipboard-17424069591778516712

Conversation

@is0692vs

@is0692vs is0692vs commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🎯 What: The testing gap addressed
This PR addresses missing test coverage for the fallback copy path in the useCopyToClipboard hook. Specifically, it ensures that when the primary navigator.clipboard.writeText API fails and the hook falls back to manipulating the DOM (creating a textarea, appending it to the body, and using document.execCommand), these DOM operations are correctly executed and properly cleaned up.

📊 Coverage: What scenarios are now tested

  • The test verifies that a textarea is created.
  • It checks that the textarea is appended to the document body.
  • It verifies that the .select() method is called on the textarea.
  • It asserts that document.execCommand("copy") is successfully executed.
  • Finally, it validates that the textarea is safely removed from the document body in the finally block to prevent DOM leakage.

Result: The improvement in test coverage
The codebase now includes explicit assertions on the fallback code path, providing a safety net to prevent accidental regressions related to legacy browser support for copy-to-clipboard functionality. Tests pass and test quality is strictly improved.


PR created automatically by Jules for task 17424069591778516712 started by @is0692vs

Greptile Summary

useCopyToClipboard の Clipboard API 失敗時に使用される DOM フォールバック処理のテスト範囲を拡充しています。

  • textarea の生成、body への追加、選択、execCommand("copy") の呼び出しを検証
  • textarea の値と、処理後の DOM クリーンアップを検証
  • コピー状態がタイマー経過後に解除されることを検証

Confidence Score: 5/5

この PR はテストのみを拡充しており、安全にマージできると判断します。

本番コードの動作は変更されておらず、追加テストは textarea の生成からコピー、削除、状態リセットまで既存のフォールバック経路を一貫して検証しています。

Important Files Changed

Filename Overview
src/hooks/tests/useCopyToClipboard.test.ts Clipboard API が失敗した場合の既存フォールバック処理とクリーンアップを具体的に検証するテストが追加されており、マージを妨げる問題は確認できませんでした。

Reviews (1): Last reviewed commit: "test: add missing tests for fallback cop..." | Re-trigger Greptile

Context used:

Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel

vercel Bot commented Aug 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
github-user-summary Ignored Ignored Aug 1, 2026 4:30am

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@is0692vs, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e2bcd45b-a93f-42f4-b682-44713d080f91

📥 Commits

Reviewing files that changed from the base of the PR and between e914034 and 0ffbe4a.

📒 Files selected for processing (1)
  • src/hooks/__tests__/useCopyToClipboard.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dosubot

dosubot Bot commented Aug 1, 2026

Copy link
Copy Markdown

📄 Knowledge review

Dosu skipped reviewing this PR because your organization has used its 200 included credits for the month. Your usage will reset on 2026-09-01. To have Dosu review this PR before then, ask your organization admin to upgrade to a pro account.


Leave Feedback Ask Dosu about github-user-summary Add Dosu to your team

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Test fallback DOM copy path in useCopyToClipboard

🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Add coverage for clipboard API failure path in useCopyToClipboard.
• Assert textarea creation, selection, execCommand("copy"), and DOM cleanup.
• Verify copied state toggles true then resets after timeout.
Diagram

graph TD
  T["useCopyToClipboard.test.ts"] --> H["useCopyToClipboard()"] --> W["navigator.clipboard.writeText"] --> D{"writeText fails?"}
  D -- "yes" --> DOM["Create/append textarea"] --> X["document.execCommand('copy')"] --> C["Remove textarea (finally)"]
Loading
High-Level Assessment

The approach is appropriate: it exercises the real fallback behavior via targeted spies (createElement/appendChild/removeChild/select) and verifies cleanup in the finally path, which is the main regression risk.

Files changed (1) +44 / -0

Tests (1) +44 / -0
useCopyToClipboard.test.tsAdd test for DOM-based fallback copy path and cleanup +44/-0

Add test for DOM-based fallback copy path and cleanup

• Adds a new test that forces navigator.clipboard.writeText to reject, then asserts the hook’s fallback DOM flow (textarea creation, append, select, execCommand('copy')). Verifies the textarea is removed in cleanup and that the copied state toggles and resets after the timeout.

src/hooks/tests/useCopyToClipboard.test.ts

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 30 rules

Grey Divider


Remediation recommended

1. Select assertion too broad 🐞 Bug ⚙ Maintainability
Description
The new test only asserts that HTMLTextAreaElement.prototype.select was called, but does not
verify it was called on the textarea created by the fallback path, so it could pass due to an
unrelated textarea selecting itself. This weakens the intended regression coverage for the specific
fallback textarea selection step.
Code

src/hooks/tests/useCopyToClipboard.test.ts[R258-269]

+    const selectSpy = vi.spyOn(HTMLTextAreaElement.prototype, "select");
+
+    const { result } = renderHook(() => useCopyToClipboard());
+
+    await act(async () => {
+      await result.current.copyToClipboard("fallback text");
+    });
+
+    expect(createElementSpy).toHaveBeenCalledWith("textarea");
+    expect(appendChildSpy).toHaveBeenCalled();
+    expect(selectSpy).toHaveBeenCalled();
+    expect(document.execCommand).toHaveBeenCalledWith("copy");
Evidence
The hook’s fallback path calls textArea.select() on the created textarea, but the test’s current
toHaveBeenCalled() assertion does not ensure the call was made on that specific element instance.

src/hooks/useCopyToClipboard.ts[35-58]
src/hooks/tests/useCopyToClipboard.test.ts[251-279]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test spies on `HTMLTextAreaElement.prototype.select` and asserts only `toHaveBeenCalled()`. That does not prove the fallback code called `select()` on the specific textarea created by `document.createElement('textarea')`, so the test can pass even if the wrong element is selected.

## Issue Context
`useCopyToClipboard` creates a textarea and calls `textArea.select()` before `document.execCommand("copy")`.

## Fix Focus Areas
- src/hooks/__tests__/useCopyToClipboard.test.ts[258-279]

## Suggested fix
After extracting `textarea` from `createElementSpy.mock.results`, assert the receiver of the `select()` call matches it, e.g.:

- `expect(selectSpy.mock.instances).toContain(textarea);` (or `mock.contexts` if preferred)
- Optionally also assert call count: `expect(selectSpy).toHaveBeenCalledTimes(1)` to reduce noise from unrelated calls.

This keeps the prototype spy approach but makes the assertion specific to the created textarea.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +258 to +269
const selectSpy = vi.spyOn(HTMLTextAreaElement.prototype, "select");

const { result } = renderHook(() => useCopyToClipboard());

await act(async () => {
await result.current.copyToClipboard("fallback text");
});

expect(createElementSpy).toHaveBeenCalledWith("textarea");
expect(appendChildSpy).toHaveBeenCalled();
expect(selectSpy).toHaveBeenCalled();
expect(document.execCommand).toHaveBeenCalledWith("copy");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Select assertion too broad 🐞 Bug ⚙ Maintainability

The new test only asserts that HTMLTextAreaElement.prototype.select was called, but does not
verify it was called on the textarea created by the fallback path, so it could pass due to an
unrelated textarea selecting itself. This weakens the intended regression coverage for the specific
fallback textarea selection step.
Agent Prompt
## Issue description
The test spies on `HTMLTextAreaElement.prototype.select` and asserts only `toHaveBeenCalled()`. That does not prove the fallback code called `select()` on the specific textarea created by `document.createElement('textarea')`, so the test can pass even if the wrong element is selected.

## Issue Context
`useCopyToClipboard` creates a textarea and calls `textArea.select()` before `document.execCommand("copy")`.

## Fix Focus Areas
- src/hooks/__tests__/useCopyToClipboard.test.ts[258-279]

## Suggested fix
After extracting `textarea` from `createElementSpy.mock.results`, assert the receiver of the `select()` call matches it, e.g.:

- `expect(selectSpy.mock.instances).toContain(textarea);` (or `mock.contexts` if preferred)
- Optionally also assert call count: `expect(selectSpy).toHaveBeenCalledTimes(1)` to reduce noise from unrelated calls.

This keeps the prototype spy approach but makes the assertion specific to the created textarea.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant