diff --git a/atest/acceptance/keywords/draganddropframe.robot b/atest/acceptance/keywords/draganddropframe.robot
new file mode 100644
index 000000000..e18e40300
--- /dev/null
+++ b/atest/acceptance/keywords/draganddropframe.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Documentation Tests for the custom Drag And Drop To Frame keyword
+... in cross-frame drag-and-drop scenarios.
+Resource ../resource.robot
+Test Setup Go To Page "frames/draganddrop.html"
+Force Tags draganddrop
+
+*** Test Cases ***
+Drag And Drop To Frame Works With Local HTML
+ [Documentation] Verifies successful cross-frame drag-and-drop from default content to a target inside an iframe.
+ Wait Until Page Contains Element id=source timeout=10s
+ Drag And Drop To Frame id=source id=target id=previewFrame
+ Select Frame id=previewFrame
+ Element Should Contain id=target Dropped Successfully!
+ Unselect Frame
+
+Drag And Drop To Frame Returns To Default Content
+ [Documentation] Verifies that the keyword returns to default content after execution.
+ Wait Until Page Contains Element id=source timeout=10s
+ Drag And Drop To Frame id=source id=target id=previewFrame
+ Element Should Be Visible id=previewFrame
+
+Drag And Drop To Frame Hides Source Element
+ [Documentation] Verifies that the source element becomes hidden after a successful drop.
+ Wait Until Page Contains Element id=source timeout=10s
+ Drag And Drop To Frame id=source id=target id=previewFrame
+ Element Should Not Be Visible id=source
+
+Standard Drag And Drop Fails When Target Is Inside Frame
+ [Documentation] Verifies that the standard Drag And Drop keyword cannot complete this cross-frame scenario.
+ Wait Until Page Contains Element id=source timeout=10s
+ Run Keyword And Expect Error * Drag And Drop id=source id=target
+ Select Frame id=previewFrame
+ Element Should Not Contain id=target Dropped Successfully!
+ Unselect Frame
+
+Drag And Drop To Frame Fails With Invalid Frame
+ [Documentation] Verifies that the keyword fails when the frame locator is invalid.
+ Wait Until Page Contains Element id=source timeout=10s
+ Run Keyword And Expect Error * Drag And Drop To Frame
+ ... id=source id=target id=missingFrame
+
+Drag And Drop To Frame Fails With Invalid Target
+ [Documentation] Verifies that the keyword fails when the target element is not found inside the iframe.
+ Wait Until Page Contains Element id=source timeout=10s
+ Run Keyword And Expect Error * Drag And Drop To Frame
+ ... id=source id=missingTarget id=previewFrame
\ No newline at end of file
diff --git a/atest/resources/html/frames/draganddrop.html b/atest/resources/html/frames/draganddrop.html
new file mode 100644
index 000000000..b3aeb0520
--- /dev/null
+++ b/atest/resources/html/frames/draganddrop.html
@@ -0,0 +1,95 @@
+
+
+
+
+ Custom Mouse-Based Cross-Frame Drag Test (Fixed with Overlay)
+
+
+
+
+ Click & hold blue box (outside), drag ANYWHERE (including into green area inside iframe), release → drops!
+
+
+ Drag Me!
(outside iframe)
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SeleniumLibrary/keywords/element.py b/src/SeleniumLibrary/keywords/element.py
index c61076286..101b7ecdc 100644
--- a/src/SeleniumLibrary/keywords/element.py
+++ b/src/SeleniumLibrary/keywords/element.py
@@ -1293,4 +1293,41 @@ def get_css_property_value(
| ${color}= | `Get CSS Property Value` | css:button.submit | background-color |
| ${size}= | `Get CSS Property Value` | id:username | font-size |
"""
- return self.find_element(locator).value_of_css_property(css_property)
\ No newline at end of file
+ return self.find_element(locator).value_of_css_property(css_property)
+
+ @keyword('Drag And Drop To Frame')
+ def drag_and_drop_to_frame(
+ self, locator: Locator, target: Locator, frame: Locator,
+ ) -> None:
+ """
+ Drags the element identified by ``locator`` from default content and drops it onto
+ the ``target`` element inside the specified iframe.
+
+ The ``locator`` argument is the locator of the dragged element in default content,
+ the ``target`` is the locator of the drop target inside the iframe, and the
+ ``frame`` is the locator of the iframe containing the target.
+
+ See the `Locating elements` section for details about the locator syntax.
+
+ This keyword is designed for cross-frame drag-and-drop scenarios where the standard
+ `Drag And Drop` keyword fails because it cannot switch contexts mid-action.
+
+ Example:
+ | Drag And Drop To Frame | css:div#draggable | css:div.drop-target | id:my-iframe |
+
+ Note: This assumes the source is in the default content and the target is inside
+ the iframe.
+ """
+ source_element = self.find_element(locator)
+ action = ActionChains(self.driver, duration=self.ctx.action_chain_delay)
+ action.click_and_hold(source_element).perform()
+
+ try:
+ frame_element = self.find_element(frame)
+ self.driver.switch_to.frame(frame_element)
+ target_element = self.find_element(target)
+
+ action = ActionChains(self.driver, duration=self.ctx.action_chain_delay)
+ action.move_to_element(target_element).release().perform()
+ finally:
+ self.driver.switch_to.default_content()
\ No newline at end of file
diff --git a/utest/test/api/test_plugins.py b/utest/test/api/test_plugins.py
index 16f5bd154..487cf5cdc 100644
--- a/utest/test/api/test_plugins.py
+++ b/utest/test/api/test_plugins.py
@@ -22,7 +22,7 @@ def setUpClass(cls):
def test_no_libraries(self):
for item in [None, "None", ""]:
sl = SeleniumLibrary(plugins=item)
- self.assertEqual(len(sl.get_keyword_names()), 183)
+ self.assertEqual(len(sl.get_keyword_names()), 184)
def test_parse_library(self):
plugin = "path.to.MyLibrary"