How to click a menu item present inside an iframe in cypress? - cypress

I have a menu item named as Transform table after clicking on it more items are shown for selection. These are all present inside an iframe. I want to click on the options available inside Transform Table, but when I am searching for the options the main pop gets closed. Please suggest some way to keep it open and the select the options in it.
const body = $iframe.contents().find('body');
let getElement = cy.wrap(body);
getElement.find(getdatasourcelocator.SearchBox).should('be.visible', { timeout: 30000 }).type(datasourceType);
getElement = cy.wrap(body);
getElement.find('.textCsv').click();
getElement = cy.wrap(body);
getElement.find(getdatasourcelocator.URL).type(entityURL);
getElement = cy.wrap(body);
getElement.find('button').contains('Next').click();
getElement = cy.wrap(body);
getElement.wait(15000);
getElement.find('button').contains('Transform table').click().then(()=>{
cy.get('button[data-automation-id="PromoteHeaders"]').should('be.visible');
cy.contains('li','Use first row as headers').should('be.visible', { timeout: 30000 }).click()
});
});
}```

Unfortunately, you cannot target elements or interact with anything in an iframe - regardless of it being the same domain or cross-domain iframe. Here is a known issue.
As workaround, you can try to use something from the comments:
Add custom command.
Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
return new Cypress.Promise(resolve => {
$iframe.on('load', () => {
resolve($iframe.contents().find('body'));
});
});
});
And use this command.
// for <iframe id="foo" src="bar.html"></iframe>
cy.get('#foo').iframe().find('.bar').should('contain', 'Success!');

Related

ag grid Passing KeyPress/Enter event to apply filter

I want to use the same logic when I press the APPLY button but with the ENTER key.
How do I do that?
filterParams: {
closeOnApply:true,
buttons: ['reset', 'apply'],
values: parentCampaignAndNodes.PaymentGroups
},
As you might have found out by now, you can remove the Apply button (by setting filterParams: { buttons: [] } in your column definitions) and then values are submitted onchange.
The solution you ask for is indeed still not available through the AgGrid API. I do have a workaround, but beware it uses direct DOM bindings which is not recommended when working with React.
const applyFilterOnEnter: AgGridReactProps['onFilterOpened'] = ev => {
const inputElem = ev.eGui.querySelector('.ag-filter-body .ag-input-field');
const applyButtonElem = ev.eGui.querySelector('.ag-filter-apply-panel button[ref=applyFilterButton]');
if (inputElem && applyButtonElem) {
inputElem.addEventListener('keydown', keyEv => {
if ((keyEv as KeyboardEvent).key === 'Enter') {
(applyButtonElem as HTMLButtonElement).click();
}
});
}
};
return <AgGridReact
onFilterOpened={applyFilterOnEnter}
/>

Unable to Drag and drop into iframe using cypress

Hi I have to drag a component which is outside a frame and drop into a iframe body(dragable source)
but it is not draging my component into iframe dragable source
this is code which is am using for get into the iframe and it is working means it is going into the iframe and finding element
const getIframeDocument = () => {
return cy.get(".gjs-frame").its("0.contentDocument").should("exist");
};
const getIframeBody = () => {
// get the document
return (
getIframeDocument()
// automatically retries until body is loaded
.its("body")
.should("not.be.undefined")
// wraps "body" DOM element to allow
// chaining more Cypress commands, like ".find(...)"
.then(cy.wrap)
);
};
and
for drag and drop into iframe like this
getIframeBody().find("#wrapper").as("Target");
cy.get('[title="Url"]').drag("#Target");
this is not giving me any error this drag function working but at the same time drag and drop is not happening
drag and drop execution pic must see this
you can do this by using this code. You just need to change selectors according to your website.
// Define Locators.
drag_element = '.blockbuilder-content-tools .blockbuilder-content-tool:nth-
child(6)';
drop_element = '#u_body #u_row_2';
text_indentation = '[aria-label="Align center"]';
new_box_text = 'This is a new Text block. Change the text.'
// Get iframe body and then drag & drop element.
iframe_interaction(){
let ifm = cy.get('iframe');
ifm
.should(iframe => expect(iframe.contents().find('body')))
.then(iframe => cy.wrap(iframe.contents().find('body')))
.within({}, $iframe => {
cy.get(this.drag_element).drag(this.drop_element, { force: true })
cy.contains(this.new_box_text).dblclick({force: true})
cy.get(this.text_indentation).click()
})
Github Link: https://github.com/sardar-usman/Cypress--Drag-and-Drop

KendoUI PanelBar remember expanded items

I try implement Kendo UI PanelBar (see http://demos.kendoui.com/web/panelbar/images.html) If I open some items (Golf, Swimming) and next click to "Videos Records", I have expanded items. But when I do refresh page (click on some link), all expanded structure is lost.
On KendoUI forum I found, that I can get only possition of selected item and after reload page I must calculate all noded. Is there any way, how can I have expanded items in my situation? If do not need, I don't want to use the html frames.
Best regards,
Peter
Thank you for your answer, was very usefull. I add here code of skeleton of jQuery which remember 1 selected item now. Required add jquery.cookie.js [https://github.com/carhartl/jquery-cookie]
function onSelect(e) {
var item = $(e.item),
index = item.parentsUntil(".k-panelbar", ".k-item").map(function () {
return $(this).index();
}).get().reverse();
index.push(item.index());
$.cookie("KendoUiPanelBarSelectedIndex", index);
//alert(index);
}
var panel = $("#panelbar").kendoPanelBar({
select: onSelect
}).data("kendoPanelBar");
//$("button").click(function () {
// select([0, 2]);
//});
function select(position) {
var ul = panel.element;
for (var i = 0; i < position.length; i++) {
var item = ul.children().eq(position[i]);
if (i != position.length - 1) {
ul = item.children("ul");
if (!ul[0])
ul = item.children().children("ul");
panel.expand(item, false);
} else {
panel.select(item);
}
}
}
// on page ready select value from cookies
$(document).ready(function () {
if ($.cookie("KendoUiPanelBarSelectedIndex") != null) {
//alert($.cookie("KendoUiPanelBarSelectedIndex"));
var numbersArray = $.cookie("KendoUiPanelBarSelectedIndex").split(',');
select(numbersArray);
}
else {
// TEST INIT MESSAGE, ON REAL USE DELETE
alert("DocumenReadyFunction: KendoUiPanelBarSelectedIndex IS NULL");
}
});
The opening of the panels happens on the client. When the page is refreshed, the browser will render the provided markup, which does not include any additional markup for the selected panel.
In order to accomplish this, you will need to somehow store a value indicating the opened panel. The easiest way to accomplish this would be with a cookie (either set by JavaScript or do an AJAX call to the server).
Then, when the panelBar is being rendered, it will use the value in the cookie to set the correct tab as the selected one.
You can use this block to work withe the selected. in this example, i am just expanding the panel item. You can do other things such as saving panel item in your dom for later use or may be saving it somewhere to use it later:
var panelBar = $("#importCvPanelbar").data("kendoPanelBar");
panelBar.bind("select", function(e) {
var itemId = $(e.item)[0].id;
panelBar.expand(itemId);// will expand the selected one
});

CKEditor dialog input field above tab elements

I'm building a simple dialog plugin to replace the default link tool. The design calls for a particular layout that is difficult to achieve with the CKEdit dialog definition: We want a single field to appear above the tab elements in the dialog (see illustration).
Can anyone suggest a way that this might be implemented? Thanks!
As far as I can tell it is not possible to achieve this using the built-in dialog definition.
I was able to get around this limitation by building my dialog plugin using the iframedialog plugin. This basically pops up a CKEditor dialog window and loads an external URL into it. You can do anything you want in that iframe, and then return the text to CKEditor when the user presses the OK button.
A simple example:
// plugins/iframelink/plugin.js
CKEDITOR.plugins.add('iframelink', {
requires: ['iframedialog'],
init: function(editor){
CKEDITOR.dialog.addIframe('iframelinkDialog',
// title
'Insert a Link',
// src
this.path + 'dialogs/link.html',
// minWidth
500,
// minHeight
250,
// onContentLoad
);
var cmd = editor.addCommand('iframelink', {exec: iframelinkOnclick});
editor.ui.addButton('iframelink', {
label: 'Insert a Link (Special Link Tool)',
command: 'iframelink',
icon: this.path + 'images/world_link.png'
});
}
});
function iframelinkOnclick(editor){
dialog = editor.openDialog('msiteslinkDialog');
};
// plugins/iframelink/dialogs/iframelink.js
$(function() {
if (typeof(window.parent.CKEDITOR) != 'undefined') {
CKEDITOR = window.parent.CKEDITOR;
var dialog = CKEDITOR.dialog.getCurrent();
var editor = dialog.getParentEditor();
// Get value of the selected text:
var selection = editor.getSelection().getSelectedText();
// Do something when the user presses the OK button:
var okListener = function(ev) {
link = yourFunctionToDoSomethingClever();
this._.editor.insertHtml(link);
dialog.removeListener("ok", okListener);
};
// Bind the OK button to your okListener method:
dialog.on("ok", okListener);
};
}
So you can make the dialog look any way you want:

jquery: bind click event to ajax-loaded elmente? live() won't work?

hey guys,
I have an input field that looks for matched characters on a page. This page simply lists anchor links. So when typing I constantly load() (using the jquery load() method) this page with all the links and I check for a matched set of characters. If a matched link is found it's displayed to the user. However all those links should have e.preventDefault() on them.
It simply won't work. #found is the container that shows the matched elements. All links that are clicked should have preventDefault() on them.
edit:
/*Animated scroll for anchorlinks*/
var anchor = '',
pageOffset = '',
viewOffset = 30,
scrollPos = '';
$(function() {
$("a[href*='#']").each(function() {
$(this).addClass('anchorLink');
$(this).bind('click', function(e) {
e.preventDefault();
//console.log('test');
anchor = $(this).attr('href').split('#')[1];
pageOffset = $("#"+anchor).offset();
scrollPos = pageOffset.top - viewOffset;
$('html, body').animate({scrollTop:scrollPos}, '500');
})
});
});
Well, I'm looking for all href's that contain a #. So I know those elements are anchors that jump to other elements. I don't want my page to jump, but rather scroll smoothly to this element with this specific #id.
This works fine when I use bind('click', ... for normal page-elements that have been loaded when the page is opened. It doesn't work for anchors that have been loaded via ajax! If I change the bind to live nothing does change for the ajax loaded elements - they still don't work. However normal anchors that have always been on the page are not triggering the function as well. So nothing works with live()!
When you say "it won't work" do you mean that your function is not been called or that you can not cancel out of the function? As far as I know you can not cancel out live events. With jQuery 1.4 you can use return false to cancel out live event propagation. Calling e.preventDefault() won't work.
Edit: right so this code should in principal work. What it still won't do is, it won't add the 'anchorLink' class to your new anchors. However if the clicks work then let me know and I will give you the right code to add the class too!
var anchor = '',
pageOffset = '',
viewOffset = 30,
scrollPos = '';
$(function() {
$("a[href*='#']").each(function() {
$(this).addClass('anchorLink');
});
$("a").live('click', function(e) {
if ($(this).attr("href").indexOf("#") > -1) {
e.preventDefault();
//console.log('test');
anchor = $(this).attr('href').split('#')[1];
pageOffset = $("#" + anchor).offset();
scrollPos = pageOffset.top - viewOffset;
$('html, body').animate({ scrollTop: scrollPos }, '500');
//nikhil: e.preventDefault() might not work, try return false here
}
});
});

Resources