Browser Library and Calendar function

Greetings. First, I am quite fresh beginner to use Browser Library and the second, I am also fresh in Testing Automation. I have used Selenium Library a few months but changed that to Browser to make test cases more stable.

However, right now I have an issue with calendar function. This calendar is possible to open by clicking icon, but after that difficulties start. I have tried Get Attribute, Click and Get Element. I have used them wrong way or there is something else I haven’t considered in this. Purpose is to select current day. This is script which works so far:
*** Settings ***

Library Browser
Library DateTime

*** Variables ***
${current_date} Get Current Date
${current_date}= Convert Date date_format=%d.%m.%Y

*** Keywords ***

Get Date
Click xpath=//*[@id=“omni-body”]/app-root/views/div/mat-sidenav-container/mat-sidenav-content/div/add-case/omni-scrollbar-container/div[4]/div/div/div/div/case-create/form/div[3]/mat-form-field/div/div[1]/div[4]/mat-datepicker-toggle/button

Screenshot from Developers Tools:

Any ideas how should I continue from this?

Usually I get messages like: waiting for selector
or, if I use click: ValueError: Argument ‘button’ got value ‘Get Current Date’ that cannot be converted to MouseButton

Hi and welcome!

Some points/tips:

Variable section

The most common source for variables are Variable sections in test case files and resource files. Variable sections are convenient, because they allow creating variables in the same place as the rest of the test data, and the needed syntax is very simple. Their main disadvantages are that values are always strings and they cannot be created dynamically. If either of these is a problem, variable files can be used instead.

The above means this snippet does not work the way you expect:

*** Variables ***
${current_date}    Get Current Date
${current_date}=    Convert Date date_format=%d.%m.%Y

${current_date} is literally Get Current Date (as a string).

  • Use code formatting when pasting code. Makes it easier to read and also spot errors. :slight_smile:

  • The error you pasted does not seem to match the Click snippet you pasted. It does indicate that the click is trying to use the string Get Current Date as the current date (see above). That error you mentioned can happen, for example, when the selector is not formatted correctly (having too many spaces, etc.).

  • The selector you pasted is very fragile since it contains the full DOM “path” to the element. Try to use only the element name, id, or a CSS class instead to make the selector more readable and also more robust (against DOM changes). You want to use the least amount of data to identify the elements you want, but still enough to ensure you target the correct elements.

Thanks for the tips. I realized that previous copy was from Resource files. My Test File looks like this: *** Settings ***

Resource …/Resources/CommonFunctionality.robot
Resource …/Resources/AuthenticateUser.robot
Resource …/Resources/SearchClient.robot
Resource …/Resources/CreateCase.robot
Resource …/Resources/GetDate.robot
Resource …/Resources/MainPage.robot

Test Setup CommonFunctionality.Start TestCase

#Test Teardown CommonFunctionality.Finnish TestCase

*** Test Cases ***

Create Case
AuthenticateUser.Authenticate user
SearchClient.Search client
CreateCase.Create Case
GetDate.Get Date
MainPage.Main Page

I have created this using selenium. Issue was with dynamic elements. I had to update and correct all the time test cases. That was the reason I changed to Browser. The content of all files are under conversion. And this is my challenge.

If I understand correctly your previous post, I should create Variables file and bring it as resource to this test case to get Date work.

Browser does make interacting with dynamic apps a bit more convenient thanks to the auto-waits, etc.

Not knowing the details, another reason for the need to constantly fix the tests could be the selectors (if they are too specific, such as containing the full path and expecting the exact DOM structure).

I should create Variables file and bring it as resource to this test case to get Date work.

That is a good option if you need the current date in many places (otherwise you could just get it inside the specific test/keyword). See the Variable files section for more information.

Thank you very much!

Hi Kalle,

One of the keys to building reliable test cases regardless of SeleniumLibrary or BrowserLibrary or any other library is to keep your xpaths to the minimum needed for reliably selecting the element you are interested in, and wherever possible try to avoid at all costs things like div[1]/div[4] because developers have a habit of adding new features (usually requested by users) that will change the order number of the element.

For your xpath:

I would try this as a first guess:

Click xpath=//*[@id=“omni-body”]//mat-datepicker-toggle/button

If that gave you a unique result then use that, if not, just add the minimum amount needed to get a unique result for example you might need to do this to narrow it down:

Click xpath=//*[@id=“omni-body”]//omni-scrollbar-container//mat-datepicker-toggle/button

So likewise for your calendar picker I would try an xpath something like:

Click xpath=//td[contains(@class, "mat-calendar-body-cell")]/div[text()='7']

Of course you can replace the ‘7’ with a variable something like:

Click xpath=//td[contains(@class, "mat-calendar-body-cell")]/div[text()='${currentday}']

Assuming that 7. helmikuuta 2022 is the date in your local? Another approach that might work for you is something like this:

	${current_date}=		Evaluate		datetime.datetime.now().strftime("%d. %B %Y")		datetime
	Click	xpath=//td[@aria-label="${current_date}"]

Just watch out that strftime %d 0 pads the numbers, so you might need to deal with that first.

Hope this was helpful,

Dave.

1 Like

This will deal with the zero padding issue:

	${current_date}=		Evaluate		datetime.datetime.now().strftime("%d %B %Y").replace("0", "", 1)		datetime

Hi! Thanks! These instructions are great! I really didn’t realize those long paths were consequences from developing software. I thought it happens because I am running tests using browsers and my first thought was they are performed by session.

This idea came partly because element id:s were changing all the time. But I will try that. Thanks, Dave!

1 Like

Those long paths are just because the element you want to hit is deep in the html, but if they have a unique id or something that can uniquely identify the element then it’s best to use a short path.

BTW in the elements tab of Developers Tools (like your screenshot above) you can type Ctrl-F (Command-F on a Mac) and type your xpath to test it out, I find this really useful for trying out different xpaths and seeing what works best.

Dave.

Hi. There is one more thing. I tried to take it forward using your advice and tips. It works, thank you. However, I have got a new issue in this same task. I tried to solve this myself, but now I have to admit that I am not sure how to continue.

OS is Windows. When I run the test, there will be error message: Evaluating expression ‘locale.setlocale(locale.LC_ALL, ‘sv_FI.UTF8’)’ failed: unsupported locale setting. I have tried to localize DateTime because otherwise I will get error about languge. RF waits following result: 10. February 2022. Calendar has 10. helmikuuta 2022.

I decided to use in locale.setlocale(locale.LC_AA, ‘sv_FI.UTF8’) instead of fi_FI because there was no that kind of language setting. I tried and got the same result. Any advice how to solve this?

Should I create a Python library as Resource and handle month conversion by using that?

My guess is its something in your underlying python setup, no robot framework. it looks like a python error.

I don’t have a windows machine, and i’m in an English local, so I wasn’t able to test this for you, I was just trying to give you something that might give you a date in your local.

Something to try for troubleshooting, try running this from your command prompt:

c:\somewhere\>python
>>> import datetime
>>> datetime.datetime.now().strftime('%d. %B %Y')
'10. February 2022'
>>>

If that errors we know it’s not robot framework, but the underlying python where the problem is, then we’ll have a better chance of figuring it out.

Dave.

Thanks for the advice. I run the script and results are here:

C:>python
Python 3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type “help”, “copyright”, “credits” or “license” for more information.

import datetime
datetime.datetime.now().strftime(’%d. %B %Y’)
‘10. February 2022’

Kalle

Interesting, that came back in English not Finnish.

I guess RF must set the locale?

I was doing some searching and found https://github.com/python/cpython/blob/main/Lib/locale.py your locale is there in the python system:

    'fa':                                   'fa_IR.UTF-8',
    'fa_ir':                                'fa_IR.UTF-8',
    'fa_ir.isiri3342':                      'fa_IR.ISIRI-3342',
    'ff_sn':                                'ff_SN.UTF-8',
    'fi':                                   'fi_FI.ISO8859-15',
    'fi_fi':                                'fi_FI.ISO8859-15',
    'fil_ph':                               'fil_PH.UTF-8',
    'finnish':                              'fi_FI.ISO8859-1',
    'fo':                                   'fo_FO.ISO8859-1',
    'fo_fo':                                'fo_FO.ISO8859-1',
    'fr':                                   'fr_FR.ISO8859-1',
    'fr_be':                                'fr_BE.ISO8859-1',

I tried this on my computer and get the same error:

c:\somewhere\>python
>>> import locale
>>> locale.setlocale(locale.LC_ALL, ‘sv_FI.UTF8’)
  File "<stdin>", line 1
    locale.setlocale(locale.LC_ALL, ‘sv_FI.UTF8’)
                                    ^
SyntaxError: invalid character '‘' (U+2018)
>>> locale.setlocale(locale.LC_ALL, ‘sv_FI’)
  File "<stdin>", line 1
    locale.setlocale(locale.LC_ALL, ‘sv_FI’)
                                    ^
SyntaxError: invalid character '‘' (U+2018)
>>> 
>>> 
>>> locale.setlocale(locale.LC_ALL, ‘fi_FI’)
  File "<stdin>", line 1
    locale.setlocale(locale.LC_ALL, ‘fi_FI’)
                                    ^
SyntaxError: invalid character '‘' (U+2018)

I’ll see if I can figure it out.

Thanks for help. I didn’t realize it could be this kind of issue. I was just wondering what I am doing wrong. This Ignorance of the Beginner…

Kalle

Well this is Interesting, this is what I get on my machine:

 % python3
Python 3.9.1 (v3.9.1:1e5d33e9b9, Dec  7 2020, 12:44:01) 
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> locale.setlocale(locale.LC_ALL, 'de_DE')
'de_DE'
>>> 
>>> datetime.datetime.now().strftime('%d. %B %Y')
'10. Februar 2022'
>>> 
>>> locale.setlocale(locale.LC_ALL, 'fi_FI')
'fi_FI'
>>> 
>>> datetime.datetime.now().strftime('%d. %B %Y')
'10. Helmikuu 2022'
>>> locale.setlocale(locale.LC_ALL, 'fi_FI.UTF8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/locale.py", line 610, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting
>>> 
>>> locale.setlocale(locale.LC_ALL, 'sv_FI')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/locale.py", line 610, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting
>>> 

See if you get the same?

If that works, then this should do what you want, I just never expected to need to do this. but this should give you plenty of flexibility, and you can rename the python functions with finnish names if you want.

[fi_date.py]

import datetime
import locale

def finnish_date_today():
	retstr = finnish_date(datetime.datetime.now().strftime('%Y-%m-%d'))
	return retstr


def finnish_date(inp_date):
	locale.setlocale(locale.LC_ALL, 'fi_FI')
	retstr = datetime.datetime.fromisoformat(inp_date).strftime('%d. %B %Y')
	if retstr[0] == "0":
		retstr = retstr[1:]
	return retstr

[fi_date.robot]

*** Settings ***
Library    fi_date.py
Library		String


*** Test Cases ***
FI date test
	${mydate}= 	Finnish Date	2022-01-13
	Log    ${mydate}

	${mydate}= 	Finnish Date	2022-01-07
	Log    ${mydate}

FI date test today
	${MyDateU}= 	Finnish Date Today
	${mydatel} =	Convert To Lower Case	${MyDateU}
	Log    ${mydatel}

Hi

I got this:

C:>python
Python 3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type “help”, “copyright”, “credits” or “license” for more information.

locale.setlocale(locale.LC_ALL, ‘de_DE’)
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘locale’ is not defined. Did you mean: ‘locals’?

And:

datetime.datetime.now().strftime(’%d. %B %Y’)
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘datetime’ is not defined

Something wrong in my Python version? Could it be possible, that there’s no datetime module at all in my settings?

Kalle

you need to do the imports before you use them:

import datetime
import locale

% python3
Python 3.9.1 (v3.9.1:1e5d33e9b9, Dec  7 2020, 12:44:01) 
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import datetime
>>> import locale
>>> 
>>> locale.setlocale(locale.LC_ALL, 'de_DE')
'de_DE'
>>> 
>>> datetime.datetime.now().strftime('%d. %B %Y')
'10. Februar 2022'
>>> 
>>> locale.setlocale(locale.LC_ALL, 'fi_FI')
'fi_FI'
>>> 
>>> datetime.datetime.now().strftime('%d. %B %Y')
'10. Helmikuu 2022'

I got this as response:

One more thing. I am running Robot Framework in Remote Desktop. Is it possible that those settings could create interesting times for this?

There are differences in Keywords between your and my logs. You have for example:
${MyDateU} = fi.date.Finnish Date Today

I have:
${MyDateU} = = Finnish Date Today

I thought I wrote it identically. Something seem to gone wrong.

Kalle

For those keywords to work you need this line:

Library    fi_date.py

but it needs to match the name you gave the python file, also it needs to be in the same directory as the robot file or you need to give the path to the python file.