Clicking on multiple elements in order and if text is present do something - cypress

I have 4 buttons on the page and if i click them, different data is displayed for each one.
What i want to do is have a method that clicks on button 1 and check if specified text is not displayed on the page, have it click button 2 and so on until the text is displayed. Text is not always displayed on the same button section so i am not able to hardcode this in, i must search for it. If i try to check if element.contains(text) it will give an error as it is not displayed and making if else statements using the contains.size different from 0 will always go to the last else. Any ideas?
Added some sample code of what i have tried. If i can get inside the IF block and stop successfully where the text is displayed, i will make a boolean and using that i can continue with a function
cy.get(button1).click()
cy.get("body").then(($body) => {
if ($body.find(specifiedText).length > 0) {
cy.get(elementThatContainsTheText).click()
// cy.get(specifiedText).click()
} else {
cy.get(button2).click()
if ($body.find(specifiedText).length > 0) {
cy.get(elementThatContainsTheText).click()
// cy.get(specifiedText).click()
} else {
cy.get(button3).click()
if ($body.find(specifiedText).length > 0) {
cy.get(elementThatContainsTheText).click()
// cy.get(specifiedText).click()
} else {
cy.get(button4).click()
cy.get(elementThatContainsTheText).click()
// cy.get(specifiedText).click()
}
}
}
})
cy.get(button1).click()
cy.get("body").then(($body) => {
if (cy.get(elementThatContainsTheText).contains("text") > 0) {
cy.log("text is not here")
} else {
cy.get(button2).click()
if (cy.get(elementThatContainsTheText).contains("text") > 0) {
cy.log("text is not here button2")
} else {
cy.get(button3).click()
if (cy.get(elementThatContainsTheText).contains("text") > 0) {
cy.log("i should be here")
} else {
cy.log("last else, why am i here?")
}
}
}
})

Related

Bootstrap collapse plugin and complexity in rendering pdf after expanding all collapsible elements

I have 3+ collapsed elements in my html. They have ids for e.g.collapse1, collapse2 and collapse3.
I have to generate a PDF with all the collapsed elements shown (expanded).
Some of the elements might be expanded by user. So if an element is not expanded
I need to use javascript to expand and show the item and finally render the PDF.
There are few problems I faced.
If I use javascript collapse plugin, and show collapsed item, its asynchronous.
I have to subscribe to "shown.bs.collapse" event and inside the event handler I have to render PDF.
"shown.bs.collapse" event is not fired when an element is already opened. Because of this
I need to create flags to determine whether element is already shown and need to write if / else
logic to resolve this.
Below is the complex logic I wrote (its only pseudo code). Can this be simplified?
downloadPDF() {
flag1 = collapse1.hasClass('show')
flag2 = collapse2.hasClass('show')
flag3 = collapse3.hasClass('show')
$("#collapse1").on('shown.bs.collapse', function() {
if (!flag2)
collapse2.show()
else
if (!flag3) {
collapse3.show();
} else {
generatePDF()
}
}
$("#collapse2").on('shown.bs.collapse', function(){
if (!flag3)
collapse3.show()
else
generatePDF()
}
$("#collapse3").on('shown.bs.collapse', function(){
generatePDF()
}
if (!flag1) {
collapse1.show()
}
if (flag1 && !flag2) {
collapse2.show();
}
if (flag1 && flag2 && !flag3) {
collapse3.show();
}
if (flag1 && flag2 && flag3) {
generatePDF();
}
}

SmoothScroll Offset

Apologies, I realise that similar questions have been asked on here, but I'm a coding noob attempting to build my first website. Basically, I'd like to offset my SmootScroll target to avoid my nav-bar obscuring content. Here's what my code looks like:
// Scroll
function InitScroll() {
$('body').smoothScroll({
delegateSelector: 'nav a',
speed: 2000
});
}
// Fixed Navigation
function initFixedNav() {
$(window).scroll(function(){
if ( $(this).scrollTop() > 0) {
$("#navigation").removeClass("top-nav").addClass("fix-nav");
}
else if($(this).scrollTop() <= 0) {
$("#navigation").removeClass("fix-nav").addClass("top-nav");
}
});
}

If Rectangle doesn't Contains Mouse Position

I have a Rectangle which I can touch with this command below.
if ((mouse.LeftButton == ButtonState.Pressed )&&
TextureRectangle.Contains((int)MousePos.X,(int)MousePos.Y))
{
// Action;
}
But is there a Command like "Not Contains", so I wanna do something else if the user touch out of the "TextureRectangle" area?
When I click to the Rectangle that both actions starts. I really dont know where the problem is.
if (mouse.LeftButton == ButtonState.Pressed){
if(TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y)) {
music1.Play();
}
else{
music2.Play();
}
}
my problem is that music1 and music2 plays at same time if i click on the Rectangle, i want that when i click on the Rectangle that music1 plays only (here is the problem , both starts to play)and when i click out of the Rectangle should start only music2 to play ( this case is ok)
I would strongly recommend you to get a programming book / ebook and start reading it. This is basic computer logic stuff.
if (mouse.LeftButton == ButtonState.Pressed)
{
if (TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y))
{
// inside
}
else
{
// outside
}
}
OR
if (mouse.LeftButton == ButtonState.Pressed)
{
if (!TextureRectangle.Contains((int)MousePos.X, (int)MousePos.Y))
{
// outside
}
else
{
// inside
}
}

Custom events for Telerik Upload Control

I was trying to use Telerik Upload control in my project. In that, i need to use custom button. The button is shown when upload control has atleast 1 file. If no file is present then the custom button to be hidden.
Here is my View code : (note: createitems is my button ID)
function UploadSuccess(e) {
$('#createitems').show();
}
function UploadRemove(e) {
var files = e.files;
if (files.length > 0) {
$('#createitems').hide();
}
else {
$('#createitems').show();
}
}
Can anyone tell me the possibilities for this issue.
You can hide and show your button if file atleast 1
function UploadRemove(e) {
var files = e.files;
if (files.length > 0) {
$('#createitems').show();
}
else {
$('#createitems').hide();
}
}

how to make jqgrid advanced search dialog keyboard accessible

Answer in how to enable enter in jqgrid advanced search window describes how to enable enter and other keys in jqgrid advanced search dialog.
After clicking Add group, Add subgrup, Delete rule or Delete group button in advanced search dialog Enter and other keys are still ignored. How set focus to added element or after delete remaining element to enable Enter and other keys?
The current version of the Advanced Searching dialog (see definition of jqFilter in the grid.filter.js) recreate all controls of the dialog on change of someone. See the code of reDraw which looks
this.reDraw = function() {
$("table.group:first",this).remove();
var t = this.createTableForGroup(p.filter, null);
$(this).append(t);
if($.isFunction(this.p.afterRedraw) ) {
this.p.afterRedraw.call(this, this.p);
}
};
How one can see the first line $("table.group:first",this).remove(); delete the content of all filter. The current focus will be lost and one have the problems which you described.
I suggest to fix the code of reDraw using document.activeElement element which was introduced in Internet Explorer originally (at least in IE4) and which is supported now in all web browsers because it's part of HTML5 standard (see here). The element which has focus originally will be destroyed and one will unable to set focus on it later. So I suggest to save the element name of the element and it's classes (like input.add-group or input.add-rule.ui-add) and to find the position of the element on the searching dialog. Later, after the dialog element will be recreated we'll set focus on the element with the same index.
I suggest to change the code of reDraw to the following
this.reDraw = function() {
var activeElement = document.activeElement, selector, $dialog, activeIndex = -1, $newElem, $buttons,
buttonClass,
getButtonClass = function (classNames) {
var arClasses = ['add-group', 'add-rule', 'delete-group', 'delete-rule'], i, n, className;
for (i = 0, n = classNames.length; i < n; i++) {
className = classNames[i];
if ($.inArray(className, arClasses) >= 0) {
return className;
}
}
return null;
};
if (activeElement) {
selector = activeElement.nodeName.toLowerCase();
buttonClass = getButtonClass(activeElement.className.split(' '));
if (buttonClass !== null) {
selector += '.' + buttonClass;
if (selector === "input.delete-rule") {
$buttons = $(activeElement).closest('table.group')
.find('input.add-rule,input.delete-rule');
activeIndex = $buttons.index(activeElement);
if (activeIndex > 0) {
// find the previous "add-rule" button
while (activeIndex--) {
$newElem = $($buttons[activeIndex]);
if ($newElem.hasClass("add-rule")) {
activeElement = $newElem[0];
selector = activeElement.nodeName.toLowerCase() + "." +
getButtonClass(activeElement.className.split(' '));
break;
}
}
}
} else if (selector === "input.delete-group") {
// change focus to "Add Rule" of the parent group
$newElem = $(activeElement).closest('table.group')
.parent()
.closest('table.group')
.find('input.add-rule');
if ($newElem.length > 1) {
activeElement = $newElem[$newElem.length-2];
selector = activeElement.nodeName.toLowerCase() + "." +
getButtonClass(activeElement.className.split(' '));
}
}
$dialog = $(activeElement).closest(".ui-jqdialog");
activeIndex = $dialog.find(selector).index(activeElement);
}
}
$("table.group:first",this).remove();
$(this).append(this.createTableForGroup(this.p.filter, null));
if($.isFunction(this.p.afterRedraw) ) {
this.p.afterRedraw.call(this, this.p);
}
if (activeElement && activeIndex >=0) {
$newElem = $dialog.find(selector + ":eq(" + activeIndex + ")");
if ($newElem.length>0) {
$newElem.focus();
} else {
$dialog.find("input.add-rule:first").focus();
}
}
};
Like one can see on the next demo the focus in the Searching Dialog stay unchanged after pressing on the "Add subgroup" or "Add rule" buttons. I set it on the "Add rule" buttons of the previous row group in case of pressing "Delete group".
One more demo use jQuery UI style of the buttons and the texts in the buttons (see the answer). After clicking on the "Delete" (rule or group) button I tried to set the focus to the previous "Add Rule" button because setting of the focus on another "Delete" (rule or group) button I find dangerous.
Additionally in the demo I use
afterShowSearch: function ($form) {
var $lastInput = $form.find(".input-elm:last");
if ($lastInput.length > 0) {
$lastInput.focus();
}
}
because it seems me meaningful to set initial focus on the last input field at the dialog opening.
UPDATED: I find additionally meaningful to set focus on the current clicked buttons "Add subgroup", "Add rule" or "Delete group". The advantage one sees in the case it one first click some button with the mouse and then want to continue the work with keyboard. So I suggest to change the line
inputAddSubgroup.bind('click',function() {
to
inputAddSubgroup.bind('click',function(e) {
$(e.target).focus();
To change the line
inputAddRule.bind('click',function() {
to
inputAddRule.bind('click',function(e) {
$(e.target).focus();
and the line
inputDeleteGroup.bind('click',function() {
to
inputDeleteGroup.bind('click',function(e) {
$(e.target).focus();
and the line
ruleDeleteInput.bind('click',function() {
to
ruleDeleteInput.bind('click',function(e) {
$(e.target).focus();

Resources