Calabash: Select a date from a UIDatePickerview - iphone

In Calabash Automation testing on iPhone. I need to select a date from a date picker. Please guide me with a ruby step definition.
I want something like
Then I scroll datepicker to date "2002-10-22"

I made a solution after some research. This code is not bulletproof but it works fine for me. I guess someone will get a help from this. if anyone knows how to improve this. please add it here.
In step definitions I add..
Then /^I scroll datepicker to date "1985-01-01"
# Date Format "1985-01-01"
# make sure date picker is up
should_see_date_picker()
is_picker_in_date_mode()
maxdate = picker_maximum_date_time()
target = Date.parse(target_date)
current = Date.parse(datequery())
if(maxdate<target)
screenshot_and_raise "Target date'#{target}' is larger than maximum date'#{maxdate}' in date picker"
end
limit = 100
# => set year
count = 0
dir = (target.year < current.year) ? "down" : "up"
until (target.year == Date.parse(datequery()).year) or (count==limit) do
date = Date.parse(datequery())
scroll_date_component(dir, 2, date.year)
# puts("Inside the loop1 '#{count}'=> '#{date.year}'" )
count += 1
end
# => set month
count = 0
dir = (target.month < current.month) ? "down" : "up"
until (target.month == Date.parse(datequery()).month) or (count==limit) do
date = Date.parse(datequery())
scroll_date_component(dir, 0, date.month)
# puts("Inside the loop2 '#{count}'=> '#{date.month}'" )
count += 1
end
# => set day
count = 0
dir = (target.day < current.day) ? "down" : "up"
until (target.day == Date.parse(datequery()).day) or (count==limit) do
date = Date.parse(datequery())
scroll_date_component(dir, 1, date.day)
# puts("Inside the loop3 '#{count}'=> '#{date.day}'" )
count += 1
end
end
#########################################################
# => ##### Date picker helper methods. #####
def scroll_date_component(direction, column, component)
if(column==0)
# => Month scroll needs the month name string
if (direction.eql? "up")
month_str = Date::MONTHNAMES[component+1]
touch("pickerView scrollView index:#{column} label text:'#{month_str}'")
elsif (direction.eql? "down")
month_str = Date::MONTHNAMES[component-1]
touch("pickerView scrollView index:#{column} label text:'#{month_str}'")
end
else
# => Day and year scrolls are numeric
if (direction.eql? "up")
touch("pickerView scrollView index:#{column} label text:'#{component + 1}'")
elsif (direction.eql? "down")
touch("pickerView scrollView index:#{column} label text:'#{component - 1}'")
end
end
sleep(0.3)
end
def datequery()
return query("datePicker","date").first
end
def should_see_date_picker ()
if query("datePicker", :date).empty?
screenshot_and_raise "Could not find date picker"
end
end
def is_picker_in_date_mode()
res = query("datePicker", :datePickerMode)
screenshot_and_raise "expected to see a date picker" if res.empty?
screenshot_and_raise "expected to see UIDatePickerModeDate" if res.first!=1
end
def picker_maximum_date_time()
res = query("datePicker", :maximumDate)
screenshot_and_raise "expected to see a date picker" if res.empty?
return DateTime.parse(res.first) if (res.first)
end

That gist mentioned by Chathura is very out of date.
Calabash iOS now supports interaction with most date pickers natively.
https://github.com/calabash/calabash-ios/blob/develop/calabash-cucumber/features/step_definitions/calabash_steps.rb#L406
Scenario: I should be able to use the predefined steps to change the picker time
Then I change the date picker time to "10:45"
Scenario: I should be able to use the predefined steps to change the picker date
Then I change the date picker date to "July 28 2009"
Scenario: I should be able to use the predefined steps to change the picker date and time
Then I change the date picker date to "July 28" at "15:23"

Related

VBA to format long date with week day to short date

I am looking to take the date Friday, 08 July 2022, and convert it to 7/8/2022. I originally had a manual process to find and replace the date but if I can add it to the code it would be more efficient. The date moves to the summary tab and can be formatted there or before it moves.
Any help is appreciated, thank you!
Tea
Sub Datacleanup()
Dim c As Range, cDest As Range, lr As Long
Set cDest = Worksheets("summary").Cells(Rows.Count, "A").End(xlUp).Offset(1) 'first paste position
Set c = Worksheets("raw").Range("A1") 'start search here
lr = c.EntireColumn.Cells(Rows.Count).End(xlUp).Row 'last row of data in colA
Do While c.Row < lr
If Len(c.Value) > 0 And Application.CountA(c.EntireRow) = 1 Then
cDest.Resize(1, 3).Value = Array(c.Offset(2, 0).Value, _
c.Value, c.Offset(2, 14).Value)
Set cDest = cDest.Offset(1) ' next destination row
Set c = c.Offset(3) 'skip data block
Else
Set c = c.Offset(1) 'next row
End If
Loop
End Sub

Search a row a dates, identify a start date and end date, merge cells in row from start date to end date

I have searched high and low for examples to guide me in the development of a calendar spreadsheet. The customer has very specific guidelines.
First 11 columns contain event details are setup as filters
Row 1 is currently blank, but will be used for heading
Row 2 from column K to infinity (BXY) is the year
Row 3 from column K to BXY is the month
Row 4 from column K to BXY is the day
Other notes:
Cell K6 has the Date 1-Jul-18.
All cells in row 4 continue as =K$6+1..etc.
The week is calculated with the formula:
=CONCATENATE("WEEK ", IF((IF(MONTH(K6)>=10, WEEKNUM(K6)-WEEKNUM(DATE(YEAR(K6),10,1))+1, 53-WEEKNUM(DATE(YEAR(K6)-1,10,1))+WEEKNUM(K6)))=53,1,(IF(MONTH(K6)>=10, WEEKNUM(K6)-WEEKNUM(DATE(YEAR(K6),10,1))+1,53-WEEKNUM(DATE(YEAR(K6)-1,10,1))+WEEKNUM(K6)))))
All cells in row 2 are calculated:
=YEAR($K$6)
Now to my dilemma. I am working on a userform for the user to input all data that populates the next empty row in the spreadsheet. I can not post the code that does that, as it is on a proprietary computer system. But, that code that populates the filter range A through J works fine. This code finds the next empty row:
lastRow = ws.Cells.Find(What:="*", LookIn=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + 1
As part of the form the user inputs the start date and end date of an event. I am trying to search row 4 for the start date and end date, merge all cells between the start date and end date and insert the event title into the merged cell.
This is my code so far for searching Row 4:
For Each eventDate In .Range("K$4:BXY$4)
If IsDate(eventDate.Value) = IsDate(Me.tbStartDate.Value) Then
.Cells(lastRow, eventDate.Address(RowAbsolute:=True, ColumnAbsolute:=False)).Value = Me.tbEventName.Value
End If
Next eventDate
I am new to excel programming, and really only a hobbyist programmer. I was given this task at work and have been reading and researching examples for what I am trying to do...to no avail.
I am looking at modifying this snippet to work:
For iCounter = myLastRow To myFirstRow Step -1
If .Cells(iCounter, myCriteriaColumn).Value = myCriteria Then
.Range(.Cells(iCounter, myFirstColumn), .Cells(iCounter, myLastColumn)).Merge
Next iCounter
with this:
LastCol = sh.Cells.Find(What:="*", After:=sh.Range("A1"), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Column
Any assistance and guidance on how to accomplish this will be much appreciated.
v/r
Dusty
I figured it out, probably not the best solution, but it works:
lastRow = .Cells.Find(What:="*",_
LookIn:=xlFormulas,_
LookAt:=xlPart,_
SearchOrder:=xlByRows,_
SearchDirection:=xlPrevious).Row + 1
eventName = Me.tbID.Value + " " +_
Me.tbOpName + " " +_
Me.tbStartDate.Value + "-" +_
Me.tbEndDate.Value
startDate = Format(Me.tbStartDate.Value, "dd-mmm-yyyy;#")
endDate = Format(Me.tbEndDate.Value, "dd-mmm-yyyy;#")
For startCol = 14 to 959
startDateColumn = Format(.Cells(6, startCol).Value, "dd-mmm-yyyy;#")
If StrComp(startDate, startDateColumn, vbTextCompare) = 0 Then
For endCol = 14 to 959
endDateColumn = Format(.Cells(6, endCol).Value, "dd-mmm-yyyy;#")
If StrComp(endDate, endDateColumn, vbTextCompare) = 0 Then
.Range(.Cells(lastRow, startCol), .Cells(lastRow, endCol)).Merge
.Cells(lastRow, startCol).Value = eventName
Exit For
End If
Next endCol
End If
Next startCol

Get Every Tuesday of the month with Coldfusion

I'm currently working with jquery FullCalendar plugin to create a specific calendar.
One of my tasks I have to work out is how to get any given specific day for the month.
I'm currently using Coldfusion 10 for the server side so I'm wondering is there any specific way of getting every instance of a Tuesday into an array of dates?
Ideally I would like to do this on the server side and populate the calendar plugin.
My issue is primarily trying to source every specific day of a calendar month.
Any advice greatly appreciated.
The firstXDayOfMonth() UDF on CFLlib allows you to find the first of a given day-of-week in a given month. From there you just need to loop from that date adding 7 each iteration until the month is no long the selected month.
theMonth = month(now());
startDate = firstXDayOfMonth(3, theMonth, year(now()));
tuesdays = [];
for (date=startDate; month(date) == theMonth; date +=7){
arrayAppend(tuesdays, dateAdd("s",0, date)); // this just converts date from a number back to a date
}
writeDump(tuesdays);
Update:
Actually the approach for that UDF on CFLib is terrible. Use this variation instead:
function firstXDayOfMonth(dayOfWeek,month,year){
var firstOfMonth = createDate(year, month,1);
var dowOfFirst = dayOfWeek(firstOfMonth);
var daysToAdd = (7 - (dowOfFirst - dayOfWeek)) MOD 7;
var dow = dateAdd("d", daysToAdd, firstOfMonth);
return dow;
}
I'll update the UDF on cflib a bit later: I need to write some decent unit tests for it first, and am a bit busy # the moment.
The Short Version:
At this time, there is not a function in CF that gets all the Tuesdays. But here's an easy way to do it:
// assuming a year and month are defined already
var firstDayOfMonth = createDate( year, month, 1 );
var targetDayOfWeek = 3; // Tuesday is 3 if Sunday is 1
var dayOfWeekArray = []; // This is the outcome.
// loop through each day of the month adding the target days to the array.
for( i = 1; i LTE daysInMonth( firstDayOfMonth ); i++){
var loopingDate = createDate( year, month, i );
if( dayOfWeek( loopingDate ) == targetDayOfWeek ){
ArrayAppend( dayOfWeekArray, loopingDate );
}
}
dayOfWeekArray is an array of every Tuesday of a month.
More Detail:
Your title and post seem to conflict as far as what you're looking for, so I'm going to stick with the title, since that's why I came here...
Here's what you can do to find all the Tuesdays in a month:
Create a date Object
Loop through the days in the target month using the date Object
If the current day is Tuesday, add it to an array
Boom, you got all the Tuesdays of a month in an array
Here's the code I used (cfscript):
// assuming a year and month are defined already
var firstDayOfMonth = createDate( year, month, 1 );
var dayOfWeekArray = [];
var targetDayOfWeek = 3; // Tuesday is 3 if Sunday is 1. Do a quick writeDump in the loop if you're not sure.
for( i = 1; i LTE daysInMonth( firstDayOfMonth ); i++){
var loopingDate = createDate( year, month, i );
if( dayOfWeek( loopingDate ) == targetDayOfWeek ){
ArrayAppend( dayOfWeekArray, datePart( "d", loopingDate );
// ArrayAppend( dayOfWeekArray, loopingDate ); - use this if you'd rather have the whole date object
}
}
This gives you dayOfWeekArray which will be the date of each Tuesday of a particular month. For instance, this month (Jan 2019) will be [1, 8, 15, 22, 29]. You can change this to be the entire date object if you want - that's what I did in the short version at the top.

Execute code if it is after 1 of April

I have a simple problem but I can't seem to find an anwser.
I want to execute code:
if current date < 1 April then
do stuff
else
do other stuff
end if
I thought it was pretty easy, since I can get date and format it my way, but problem is when user has different Date format. I did something like this:
Private Sub UserForm_Initialize()
Dim rok As Long, rok_kontrola As Date
rok = Format(Date, "yyyy")
rok_kontrola = Format(Date, "dd-mm-yyyy")
If rok_kontrola < "01-04-" & rok Then
Me.Controls("rok1").Value = True
Else
Me.Controls("rok2").Value = True
End If
End Sub
Try this one:
If Date < DateSerial(Year(Date), 4, 1) Then
Me.Controls("rok1").Value = True
Else
Me.Controls("rok2").Value = True
End If

Bootstrap Datepicker defaults to 1900's when entered with 2 digit year

I am using a datepicker in a modal window in my Bootstrap application. I am using the original Datepicker from Stefan Petre. I built it where it works in a desktop and mobile using a mouse and it works fine.
Recently I had a user request to allow it to also work with a keyboard. I removed the readonly property to allow the user to enter a date in the input field. The date-format is set to 'mm/dd/yyyy'.
When I enter a date like today for example like this "12/11/13" then it will default to 1913. This isn't a huge deal as I could just train the users to use 4 digits, but I would rather just have it default to this century.
Note: This only seems to happen for the date-format with a 4 digit year. This also seems to happen in the same manner in the newer forks of Stefan's code.
Note: I am using Bootstrap 2.0.4. I am testing with Firefox.
Here is what it looks like:
In JavaScript, set the datepicker's assumeNearbyYear attribute to true, like this:
$("#dp").datepicker({
assumeNearbyYear: true
});
This happens because the Bootstrap datepicker is using JavaScript Date objects. When you create a new Date object and pass in a two digit year it will output 1900+year (see Why does Javascript evaluate a 2-digit year of 00 as 1900 instead of 2000?)
You could try to tweak the datepicker source code, but that might be too complicated.
From what I can see on http://www.eyecon.ro/bootstrap-datepicker/ there is no option to set a range for the selectable dates, but you could change the format to use two digit years.
On your screenshot I can see, that you are using the datepicker for "Arrival Date" which I assume is in the future. On the website there is an example on how to disable dates in the past.
I hope that helps.
UPDATE
I have written an event handler for your problem which should do the trick.
Javascript on http://jsfiddle.net/pCYbd/1/
$("#dp").datepicker();
$("#dp").on("keyup", function(e) {
var date, day, month, newYear, value, year;
value = e.target.value;
if (value.search(/(.*)\/(.*)\/(.*)/) !== -1) {
date = e.target.value.split("/");
month = date[0];
day = date[1];
year = date[2];
if (year === "") {
year = "0";
}
if (year.length < 4) {
newYear = String(2000 + parseInt(year));
$(this).datepicker("setValue", "" + month + "/" + day + "/" + newYear);
if (year === "0") {
year = "";
}
return $(this).val("" + month + "/" + day + "/" + year);
}
}
});
CoffeeScript on http://jsfiddle.net/pCYbd/2/
$("#dp").datepicker()
$("#dp").on "keyup", (e) ->
value = e.target.value
if value.search(/(.*)\/(.*)\/(.*)/) != -1
date = value.split("/")
month = date[0]
day = date[1]
year = date[2]
year = "0" if year == ""
if year.length < 4
newYear = String(2000 + parseInt(year))
$(#).datepicker("setValue", "#{month}/#{day}/#{newYear}")
year = "" if year == "0"
$(#).val("#{month}/#{day}/#{year}")
My JavaScript skills are not the best, but this should work.
Updating bootstrap-datepicker.js as shown in this post solved it for me https://github.com/eternicode/bootstrap-datepicker/pull/1461/commits/2ea16adad27cbc4d4dfa20b924addfb480e5b036
yyyy: function(d,v){
if (format.parts.indexOf('yyyy') > -1 && v < 1000) v = 2000+v; // this line ***
return d.setUTCFullYear(v);
},
I'm using bootstrap-datepicker v1.5.1 and if you look around line 1741 where it does the year mapping, you will notice this:
yyyy: function (d, v) {
return d.setUTCFullYear(v);
},
yy: function (d, v) {
return d.setUTCFullYear(2000 + v);
},
When you specify that the control uses a four year date "yyyy", it will only do the return d.setUTCFullYear(v);, which will get you the previous century that JavaScript gives you. When you specify that it use the two year date "yy", it will do the correct 2000+ that you need for the current century.
So if you want the correct two year date to be 2016, 2017, etc., you need to set your datepicker to use the "yy" like so:
$('#tbPurchaseDate').datepicker({
format: 'mm/dd/yy',
autoclose: true,
todayBtn: 'linked',
todayHighlight: true,
orientation: 'bottom auto'
});
Or you can change the "yyyy" setting in the bootstrap-datepicker.js to match the "yy" version, but then you'd have to remember to do that every time you update the datepicker js file via nuget. It's much easier to just change your format setting.
Of course, if you want the full 4 digit year to display in the control, then you might want to try one of the elaborate fixes listed here or just set the "yyyy" to what the "yy" is in the js file.
Or just update your code to the latest version (1.6.4 right now) and "yyyy" and "yy" are the same and you use assumeNearbyYear: true as noted in another answer here.
For me, the best solution was to customize parseDate function in bootstrap-datepicker.js file directly. Inside a function, there is variable setters_map with yyyy property which I modified a bit. Here is my solution:
yyyy: function(d,v) {
if (v.toString().length == 2 && v <= 30) {
v = 2000 + parseInt(v);
}
return d.setUTCFullYear(v);
},
In my case it was needed to convert only years that are less or equals 30.
In the update function of bootstrap-datepicker.js I added this block of code:
var str = this.element.prop('value');
var defaulted = false;
if (str.lastIndexOf("/") >= 0 && (str.match(/\//g) || []).length == 2)
{
var yr = str.substring(str.lastIndexOf("/") + 1);
if (yr.length <= 2)
defaulted = true;
}
if (this.date.getFullYear() < 2000 && defaulted) {
this.date.setFullYear(this.date.getFullYear() + 100);
}
right before the viewdate is set on this line:
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
It will work 100% if you update below two line in UTCDate() of bootstrap-datepicker.js core file:
function UTCDate(){
/* Date defaulted date from 2000 if entered date year less than 4 degit*/
if(arguments!=null && arguments[0].toString().length<4)
arguments[0] = 2000 + arguments[0];
return new Date(Date.UTC.apply(Date, arguments));
}