Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move / drag element from outside to iframe

I need to move element from outside an iframe into an iframe. My element panel is not part of iframe but my canvas is in the iframe and want to move element into it.

I tried below code :

 element_source = self._selenium.find_element(By.XPATH,
                                          '//div[@class="gjs-block-label"][contains(.,"Tooltip")]')
    element_target=self._selenium.find_element(By.CLASS_NAME,'gjs-frame')
    actions = ActionChains(self._driver)
    actions.drag_and_drop(element_source, element_target).perform()
    time.sleep(5)

It looks like the issue is that I have to switch to the iframe before I move element, but here I don't see that possibility because drag_and_drop is combined method where my element_source is out of the iframe and element_target is the iframe itself.

So if I switch before drag and drop, it can't find even element_source.

Here is demo page where I am working on : https://grapesjs.com/demo.html

In above demo left side is iframe and right panel is collection of elements.

like image 540
Helping Hands Avatar asked Apr 06 '20 05:04

Helping Hands


1 Answers

Using JS message passing as suggested in the answer linked by @supputuri might not exactly simulate a typical drag and drop as performed by an actual user.

One possible solution would be to try extending the Selenium ActionChains API and implement new method(s) that would allow you to start the drag on one frame, switch to the iframe and drop there. I know for sure that the API is extensible like that, but cannot speak for how possible or easy to implement this solution would be.

Another option is to do some calculations based on known info about elements on both frames to get the offset for where you want to drop the element, then use some appropriate method from the Actions API - either drag_and_drop_by_offset, or some combination of click_and_hold, move_by_offset, move_to_element, move_to_element_with_offset and release.

If I have the time, I'll try a couple of these and let you know if it works.


Edit: Despite what the first line of this answer says, what ended up working when I had to work with grapes myself, was some custom js that I ran using the webdriver execute_script method that just accessed the grapes js editor object which is attached to the window. Calling editor.addComponents with the content that I wanted to add did the trick. But, I had to create a mapping between the block labels that users see on the page to the internal block IDs and HTML content for that component, so I could just pass the label/name that a user sees for the component and it would get added. Maybe there is an ideal solution that mimics all the actions that an actual user does with the drag and drop, but I haven't got there yet.

like image 195
swaraj Avatar answered Nov 07 '22 10:11

swaraj