Cypress - for loop [duplicate] - cypress

This question already has an answer here:
Cypress - calendar change month, until specific month is found
(1 answer)
Closed last month.
I have a date picker where I want to click the left arrow till I go to April 2022.
First I will open the calendar and then I am using a loop. Here I am going to check whether the selected month is April, if not I am going to continue to click the left arrow. Please tell me whether this is correct.
myFunction() {
for (let i = 1; i <= 11; i += 1) {
cy.get('[style=""] > .CalendarMonth > .CalendarMonth_caption').should('have.text','April 2022')
cy.get('.DayPickerNavigation_leftButton__horizontalDefault > .DayPickerNavigation_svg__horizontal').click()
}
}

We cannot use Loops in cypress. However we can create methods similar to that. I had similar issue where I have to select a date range i.e. start and end date and click download. We have to create recursive method to navigate through months till we get the month we need.
Here is the method I created:
const curr_month = ["January","February","March","April","May","June","July","August","September","October","November","December"];
const d = new Date();
let name = curr_month[d.getMonth()];
cy.log("Name of Current Month" +name);
// ABOVE CODE WILL GIVE YOU CURRENT MONTH VALUE TO COMPATE LATER IN IF BLOCK
var monthNow;
// To go into previous months till september and select September 1
function changeMonth() {
cy.get(<CSS selector till, it contains the text of Month>).then((monthValue) => {
monthNow = monthValue.text();
cy.log("Month VALUE is " +monthNow);
if(monthNow.toLowerCase() != "september") //i have to reach till September
{
cy.get(<LEFT Arrow CSS Selector>).click();
cy.log("Left Arrow Clicked on Calendar");
changeMonth(); //Till it does not reach September, keep making recursive calls
}
else
{
cy.log("September Month Active");
}
}) //closing then
} // closing function
Hope this helps, if you still need it.

Why not using the each class from Cypress.
it('Navigating questions until 33 from bottom arrows works correctly: OK', ()=> {
let answers = [];
answers.length = 33
cy.wrap(answers).each((num, i, array) => {
cy.get('[data-cy="exam-bottom-right-nav"]').click({force: true});
});
cy.wrap(answers).each((num, i, array) => {
cy.get('[data-cy="exam-bottom-left-nav"]').click({force: true});
});
});

Related

"Zooming" a brushX domain?

I've made a timeline tool based off of Mike Bostock's old Brush & Zoom example. It works great when the date range is fairly simple but becomes unworkable when there are clusters of events (e.g. hourly) within a longer time range (e.g. days or weeks). The brush becomes too thin to be usable and the user is left trying to fiddle with zooming and panning in order to see the data (as in the example below).
As a first attempt at a solution I created a context menu for the brush and use the brush extent to redefine/filter the data based on the brush range (I may be using the wrong terms here). It 'sort of' works though it is a clunky and imprecise "one shot" method. Results and code below.
I am thinking that if I could "zoom" the brush (or "brush the brush") that would be a more interactive and user friendly way of working with this type of data situation. I've searched around for d3 examples and haven't found any. I am also concerned that my "subtimeline" approach won't be performative interactively since it redefines the date set and rebuilds the timeline.
I am interested in any ideas about how to handle this sort of data situation and/or if this "brushing the brush" is a dead end. Is there a better d3 way to handle this?
(edit: the display date for the last event above reads 10:50 – that is wrong, it should be 11:50 which is what is in the data)
// code edited for clarity
function createSubtimeline() {
subtimelineDates.push(moment(x.domain()[0], "L LT"));
subtimelineDates.push(moment(x.domain()[1], "L LT"));
updateData()
}
function updateData() {
var activeData
if (subtimelineDates.length != 0) {
var firstDate = subtimelineDates[0];
var lastDate = subtimelineDates[1];
activeData = timelineJson.events.filter(function (e) {
var startDate = moment(e.startDate, "L LT");
if (startDate.isAfter(firstDate) && startDate.isBefore(lastDate)) {
if (e.eventHidden == false) {
return true
} else {
return false
}
} else {
return false
}
});
} else {
activeData = timelineJson.events.filter(event => event.eventHidden == false);
}
var tStart = moment(activeData[0].startDate, "MM/D/YYYY h:mm:ss a");
var tEnd = moment(activeData[activeData.length - 1].startDate, "MM/D/YYYY h:mm:ss a");
// update timeline range
x.domain([tStart, tEnd]);
x2.domain([tStart, tEnd]);
}

Google Sheets - QUERY, adding a cell to hide a row

I'm hoping to use a Google Form to have my students sign up for activities. I added a column to the right of the form data where I can put an "x" once I have met with them. I have a separate tab called "Ordered" where I use QUERY to sort and show only the entries without an x. Once I meet with a student, I can put an x on the original data tab, and the entry will hide from the Ordered tab (kind of a queue for my students).
I would love to not have to switch between the 2 tabs every time I have to check someone off. Is there a way to add a similar column on the Ordered tab that will hide the finished entry?
Here is the sheet I'm referring to:
https://docs.google.com/spreadsheets/d/1fQHF0EoGLk5NEI6GvyRk4InBl-uEq0jq7qqmyOmFjy8/edit#gid=379798836
I'm sharing this sheet with other teachers who aren't familiar with spreadsheets, so the solution has to be ludite friendly.
As #Aerials said, you are likely to run into circular dependency issues here. Because of this, I'd suggest using Apps Script and get rid of the QUERY formula. You want to do the following:
Every time someone submits the form, the Ordered sheet gets updated with the new submission data.
Every time an x is added to the Form Responses 1 sheet, the corresponding row in Ordered gets removed.
Every time an x is added to the Ordered sheet, the corresponding row in Ordered gets removed, and an x gets added to the corresponding row in Form Responses 1.
A possible way to go would be something along the following lines (open the script bound to your spreadsheet by clicking Tools > Script editor):
Install an onFormSubmit trigger so that Ordered gets updated with new data every time the form is submitted. The trigger can be installed manually or programmatically, copying this function to your script and running it once:
function onFormSubmit(e) {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger("copyAndFilterData")
.forSpreadsheet(ss)
.onFormSubmit()
.create();
}
Once the trigger is installed, the function copyAndFilterData will execute every time the form is submitted. This function should updated Ordered based on the data in Form Responses 1, removing all the submission that have been marked as complete x. This function could be the following:
function copyAndFilterData() {
var ss = SpreadsheetApp.getActive();
var sheet1 = ss.getSheetByName("Form Responses 1");
var sheet2 = ss.getSheetByName("Ordered");
var sourceData = sheet1.getDataRange().getValues();
var filteredData = sourceData.filter(sourceRow => sourceRow[5] !== "x")
.sort((a, b) => a - b)
.map(sourceRow => {
sourceRow.pop();
sourceRow.splice(1, 1);
return sourceRow;
});
sheet2.getRange(1, 1, sheet2.getLastRow(), 4).clear({contentsOnly: true});
var destRange = sheet2.getRange(1, 1, filteredData.length, filteredData[0].length)
destRange.setValues(filteredData);
}
At this point, another piece of functionality would be needed: update the spreadsheet based on the addition or removal of x on any of both sheets. For this, an onEdit trigger would be needed, like this:
function onEdit(e) {
var editedSheet = e.range.getSheet();
if (editedSheet.getName() === "Form Responses 1") copyAndFilterData();
else if (editedSheet.getName() === "Ordered") removeRows(e, editedSheet);
}
Once this function is copied and the project saved, every time Form Responses 1 is edited, the Ordered sheets gets updated (function copyAndFilterData), and every time Ordered is edited, the function removeRows is fired. This function should do two things: (1) remove the row which was marked as complete in Ordered (x added) and (2) add the corresponding x to Form Responses 1. The submission dates can be compared to identify the row:
function removeRows(e, editedSheet) {
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var value = range.getValue();
if (column == 5 && row > 1 && value == "x") {
var date = editedSheet.getRange(row, 1).getValue();
var formSheet = e.source.getSheetByName("Form Responses 1")
var values = formSheet.getRange(2, 1, formSheet.getLastRow() - 1).getValues();
var markedRow = values.findIndex(value => value[0].getTime() === date.getTime());
formSheet.getRange(markedRow + 2, 6).setValue("x");
editedSheet.deleteRow(row);
}
}
Reference:
Overview of Google Apps Script
Simple Triggers
Installable Triggers

DHTMLX Scheduler custom Timeline with AM/PM days

I use the DHTMLX Scheduler in Timeline view for a project and the working hours are from 7AM to 5PM. I was able to make an AM/PM view per day but the first_hour and last_hour configs are not respected in the view. The screenshot shows more. The first event in the morning should be displayed far more left as it starts at 7:30Am.
My config:
scheduler.locale.labels.timeline_tab = "Timeline";
scheduler.locale.labels.section_custom = "Section";
scheduler.config.dblclick_create = false;
scheduler.config.edit_on_create = false;
scheduler.config.details_on_dblclick = false;
scheduler.config.details_on_create = false;
scheduler.config.start_on_monday = true;
scheduler.config.first_hour = 7;
scheduler.config.last_hour = 17;
scheduler.config.full_day = true;
scheduler.config.mark_now = false;
scheduler.config.drag_move = false;
scheduler.config.drag_resize = false;
//===============
//Configuration
//===============
scheduler.createTimelineView({
name: "timeline",
x_unit: "hour",
x_date: "%A",
x_step: 12,
x_size: 14,
x_start: 0,
x_length: 14,
y_unit: scheduler.serverList('teams'), // sections and events from same ajax call
y_property: "team_id",
render: "bar",
section_autoheight: false,
dy: 30,
dx: 100,
// first_hour: 7,
// last_hour: 17,
second_scale: {
x_unit: "day", // unit which should be used for second scale
x_date: "%D %j %M"
}
});
Any help will be appreciated.
EDIT:
After update based on the answer here the result:
first_hour, last_hour configs applied for Y-axis in Day, Week, Units views (check Documentation).
Currently, to hide hours at the beginning and end of the day in the Timeline view, you should have only 1 X-axis like in this sample. I.e. visible part of the event is from 10 to 18 because of first_hour, end_hour properties of createTimelineView method. Check the screenshot.
There is also ignore_[viewName] function which can be used to hide interval that equal to min step of the scale (12 hours in your case).
This could help solve your issue if set min step = 6 (hours) and disable 6-7 AM and 5-6 PM by addMarkedTimespan. I tried to create a snippet for you http://snippet.dhtmlx.com/46ba545ad , but found out that the second part of this condition if(date.getHours() < 6 || date.getHours() > 17){ is not working correctly. The event can be created until 6 PM. We will fix it ASAP, but now I can't specify the exact time. I suggest you use the first way with 1 scale to solve the issue.

How to set time to a variable without the date

I am trying to set a specific time to two variables but can't seem to correctly format the syntax. I want to be able to set Shift 1 and Shift 2 off of certain times indicated below.
I want to only be able to use these times in an IF statement so that a radio button can be checked by default. Day Shift button and a Night Shift button. If the current time is in between shift 1, then day shift button is checked.
Date.prototype.currentTime = function(){
return ((this.getHours()>12)?(this.getHours()-12):this.getHours()) +":"+ this.getMinutes()+((this.getHours()>12)?('PM'):'AM'); };
var d1= new Date();
var d2 = new Date();
d1.setHours(7);
d1.setMinutes(10);
d2.setHours(19);
d2.setMinutes(10);
alert(d1.currentTime());
alert(d2.currentTime());
Thanks Any help is appreciated.
You do not need to compare Date objects for your use,
just compare the hours as integers to the integer from now.getHours():
var now= new Date().getHours();
if(now>6 && now<19){
//check day shift button;
}
// else check niteshift button
You may try this:
http://jsfiddle.net/apq59j9u/
Date.prototype.currentTime = function(){
return ((this.getHours()>12)?(this.getHours()-12):this.getHours()) +":"+ this.getMinutes()+((this.getHours()>12)?('PM'):'AM'); };
var d1= new Date();
var d2 = new Date();
d1.setHours(7);
d1.setMinutes(10);
d2.setHours(19);
d2.setMinutes(10);
alert(d1.currentTime());
alert(d2.currentTime());
Getting the Data
There are a number of different ways to do this. First here is a way to get the data from the date object:
var d = new Date();
var n = d.toTimeString();
Unfortunately, this will output something like "12:30:30 GMT-0500 (Eastern Standard Time)"
You can also try the getHours() and getMinutes functions to get the hours and minutes in your current timezone.
var d = new Date();
var hours = d.getHours();
var minutes = d.getMinutes();
Setting the Data
This is pretty easy to do, just as getting the data from a date object. Use the following code to set the time to what you would like. Replace the numbers where you see 11 to conform to your needs.
NOTE: This time is in military style hours! 1 = 1am, 13 = 1pm, ect.
var d = new Date();
d.setHours(11);
d.setMinutes(11);
d.setSeconds(11);
Result: 11:11:11

smartgwt calendar getdaybodyhtml issue

I have a issue with the smartgwt calendar tool, I've customized it to assign special icon flags certain days in the month through the protected method getdaybodyhtml() of the class calendar, everything works fine except for one thing when I display the calendar on chrome(all versions) IE(7,8,9) and FF(till 14.0.1), but when I display the calendar on FF(between 15 to 19) this flags icons aren't displayed. I've made a follow to the code and I found that the html code that I defined there in the getdaybodyhtml() method is not printed.
I was looking on the smartgwt for any issue like that but i don't found anything related.
Any help would be received.
(sorry if my english is not so good, is my second language)
Here is the piece of code:
private Calendar calendar = new Calendar(){
#Override
#SuppressWarnings("deprecation")
protected String getDayBodyHTML(Date date, CalendarEvent[] events, Calendar calendar, int rowNum, int colNum) {
String value = defaultMessage != null ? defaultMessage : date.getDate()+"";
// The "events" are the events of the day
List<CalendarEvent> calendarEvents = new ArrayList<CalendarEvent>(Arrays.asList(events));
if(calendarEvents != null && calendarEvents.size() > 0) {
// Removing the tooltip and the excluded colours
removeTooltipsFromCalendar(calendar,date);
removeExcludedColoursFromCalendar(calendarEvents);
if(calendarEvents.size() == 1){
// Description contains the colour
String colour = calendarEvents.get(0).getDescription();
value = imgHTML(COASTAL_IMAGES_DIR+colour+COASTAL_IMAGE_SUFFIX, colourWidth, colourHeight, "images", "class='handCursor'", null);
}else if(calendarEvents.size() > 1){
// Might have two vessels going to the same port in the same day
Set<String> colours = new HashSet<String>();
for(CalendarEvent event : calendarEvents){
// Description contains the colour
colours.add(event.getDescription());
}
int numberOfPorts = colours.size();
for(String colour : colours){
value += "<div>";
value += imgHTML(COASTAL_IMAGES_DIR+colour+COASTAL_IMAGE_SUFFIX, colourWidth, colourHeight/numberOfPorts, "images", "class='handCursor'", null);
value += "</div>";
}
}else{
value = defaultMessage != null ? defaultMessage : date.getDate()+"";
}
}
return value;
}
};
PD: In all the versions of chrome and IE the piece of code:
value += "<div>";
value += imgHTML(COASTAL_IMAGES_DIR+colour+COASTAL_IMAGE_SUFFIX, colourWidth, colourHeight/numberOfPorts, "images", "class='handCursor'", null);
value += "</div>";
is printed ok, in fire fox till the 14 version it's printed ok, but in ff from 15 to 19 not prints the "div" and the "image". I already see the code throw firebug and the div just not apear in that firefox version(15-19).
PD: it doesn't work on last update of IE 10 too.
Are you able to see icons in following sample in SmartGWT showcase.
I'm able to see icons in above sample for April 2, April 3, April 4 and April 5 as of March 31.
CalendarEvent instances used in this sample are created for 2, 3, 4 and 5 days ahead of current date.
I'm using FireFox 19.0.2
Finally I found the issue. I don't know why but in the resent versions of Firefox, after 14 version, the gwt calendar(v 2.1) is repeating the printing of the calendar twice automatically, so when it prints the second time, it did it without the images inside the day bodies.
Solution: manually creation of code to stop the twice printing.

Resources