From 203db9d3f81a63995e6bd18afbfeb0a6308b3aef Mon Sep 17 00:00:00 2001 From: alanv Date: Thu, 24 Jul 2025 18:36:04 -0500 Subject: [PATCH 1/2] Add ability to paste HTML with actionPaste --- .../labkey/test/HtmlFragmentSelection.java | 45 +++++++++++++++++++ src/org/labkey/test/WebDriverWrapper.java | 36 ++++++++++++--- 2 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/org/labkey/test/HtmlFragmentSelection.java diff --git a/src/org/labkey/test/HtmlFragmentSelection.java b/src/org/labkey/test/HtmlFragmentSelection.java new file mode 100644 index 0000000000..d1615fe5c4 --- /dev/null +++ b/src/org/labkey/test/HtmlFragmentSelection.java @@ -0,0 +1,45 @@ +package org.labkey.test; + +import org.jetbrains.annotations.NotNull; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; + +/** + * Used when you want to put an HTML payload on the clipboard, allowing you to emulate things like copy/pasting from + * ELN/Google Docs. + */ +public class HtmlFragmentSelection implements Transferable +{ + // You might be tempted to add support for DataFlavor.stringFlavor to this class in addition to + // DataFlavor.fragmentHtmlFlavor, because that's what the examples show across the Internet do, and that's what the + // various AI tools will tell you to do, but it simply doesn't work. If you put a text and HTML payload in the Java + // clipboard it will only paste the text, and not the HTML. + private static final DataFlavor[] transferDataFlavors = {DataFlavor.fragmentHtmlFlavor}; + private final String html; + + public HtmlFragmentSelection(String html) { + this.html = html; + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + return transferDataFlavors; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavor.equals(DataFlavor.fragmentHtmlFlavor); + } + + @Override + @NotNull + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException + { + if (flavor == DataFlavor.fragmentHtmlFlavor) { + return html; + } + throw new UnsupportedFlavorException(flavor); + } +} \ No newline at end of file diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index edda455802..395a5c4c0e 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -3503,14 +3503,14 @@ public void actionClear(WebElement input) } /** - * puts the specified text into the clipboard, then pastes it into the specified element, + * puts the specified text and html into the clipboard, then pastes it into the specified element, * or whatever has focus at the moment. */ - public void actionPaste(WebElement input, String text) + public void actionPaste(WebElement input, String text, boolean isHtml) { Keys cmdKey = WebDriverUtils.MODIFIER_KEY; - setClipboardContent(text); + setClipboardContent(text, isHtml); if (input == null) { @@ -3531,16 +3531,40 @@ public void actionPaste(WebElement input, String text) } } + /** + * puts the specified text into the clipboard, then pastes it into the specified element, + * or whatever has focus at the moment. + */ + public void actionPaste(WebElement input, String text) + { + actionPaste(input, text, false); + } + public void clearClipboardContent() { setClipboardContent(" "); } - protected void setClipboardContent(String text) + protected void setClipboardContent(String text, boolean isHtml) { Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard(); - StringSelection sel = new StringSelection(text); - c.setContents(sel, sel); + Transferable sel; + + if (isHtml) + { + sel = new HtmlFragmentSelection(text); + } + else + { + sel = new StringSelection(text); + } + + c.setContents(sel, null); + } + + protected void setClipboardContent(String text) + { + setClipboardContent(text, false); } public String getClipboardContent() throws IOException, UnsupportedFlavorException From 2daf839b3644b02b70e0df100ccc5e5677c76dd0 Mon Sep 17 00:00:00 2001 From: alanv Date: Mon, 28 Jul 2025 12:59:19 -0500 Subject: [PATCH 2/2] HtmlFragmentSelection: Move to util package --- src/org/labkey/test/WebDriverWrapper.java | 1 + src/org/labkey/test/{ => util}/HtmlFragmentSelection.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename src/org/labkey/test/{ => util}/HtmlFragmentSelection.java (98%) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 395a5c4c0e..140cdffe4b 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -53,6 +53,7 @@ import org.labkey.test.util.EscapeUtil; import org.labkey.test.util.Ext4Helper; import org.labkey.test.util.ExtHelper; +import org.labkey.test.util.HtmlFragmentSelection; import org.labkey.test.util.LabKeyExpectedConditions; import org.labkey.test.util.LogMethod; import org.labkey.test.util.LoggedParam; diff --git a/src/org/labkey/test/HtmlFragmentSelection.java b/src/org/labkey/test/util/HtmlFragmentSelection.java similarity index 98% rename from src/org/labkey/test/HtmlFragmentSelection.java rename to src/org/labkey/test/util/HtmlFragmentSelection.java index d1615fe5c4..36cb7069d0 100644 --- a/src/org/labkey/test/HtmlFragmentSelection.java +++ b/src/org/labkey/test/util/HtmlFragmentSelection.java @@ -1,4 +1,4 @@ -package org.labkey.test; +package org.labkey.test.util; import org.jetbrains.annotations.NotNull;