Format String - "Unknown engine "template" while parsing selector"

Hello, I recently upgraded RF from 7.0.1 to 7.1 and noticed a difference regarding how selectors/locators are being put together in my test cases.

For instance, part of a test would look like this:
${timeSelector} Format String template=${variable X} beginTime=${beginTime}
Click selector=${timeSelector}

In this case, ${variableX} would be defined elsewhere as “css=ul[id*=‘P2020_BEGINTIME_HIDDEN’] div[aria-label=‘{beginTime}’]”

This used to work perfectly, but since upgrading to 7.1 I get errors like “Unknown engine “template” while parsing selector”. The solution for me is to remove the ‘template=’ part and then it works again. But I don’t understand why this happens. In the release notes of RF 7.1 something is mentioned about “Format String: Allow using template strings containing = without escaping” so I guess it has something to do with this. Can someone explain why the old syntax of using ‘template=${variable X}’ no longer works in this case and how I should go about this? Thanks.

Hi John,

Is the Format String keyword a keyword you created? it might pay to show that keyword, as that might give a clue as to what the problem is?

Also a tip: use use 3 backticks (```) before and after your robot code, so the formatting is preserved

Dave.

Hello Dave, Format String is a keyword from the String Library (https://robotframework.org/robotframework/latest/libraries/String.html#Format%20String).

I’ll repost the code snippet below in a better format:

${timeSelector} Format String template=${variable X} beginTime=${beginTime}
Click selector=${timeSelector}

with
${variable X} = "css=ul[id*='P2010_BEGINTIME_HIDDEN'] div[aria-label='{beginTime}']"

This results in

Error: locator.click: Unknown engine “template” while parsing selector template=css=ul[id*=‘P2010_BEGINTIME_HIDDEN’] div[aria-label=‘11:45’]

Call log:

  • waiting for locator(‘iframe[title='Manage hours']’).contentFrame().locator(‘template=css=ul[id*='P2010_BEGINTIME_HIDDEN'] div[aria-label='11:45']’)

So it seems the word ‘template’ now made its way into the locator url itself. In version 7.0.1 this used to work fine, but no longer in version 7.1. If I remove the ‘template=’ from the code like this, it works:

${timeSelector} Format String ${variable X} beginTime=${beginTime}
Click selector=${timeSelector}

But I would like to understand what happens here :slight_smile: .

Looks like it was a bug fix

1 Like

Yes, that is what I found out in the release notes. But I don’t really get what that changed for my existing code. It seems I cannot use ‘template=’ anymore, but to be honest I also don’t know why that was used in my code in the first place (it was made by someone else). I only know it worked before and now it doesn’t, unless I remove the ‘template=’ part. So why do I have to change the syntax on my end for this to work again? I would like to understand :slight_smile:

Didnt read check the patch but but afaik, your code worked by “accident”. template was not named argument eg, kwarg in python but because of how robot worked before the change and it saw there was = to be passed into keyword, it was considered to be named argument while it was not.

1 Like

Yeah, this is caused by the aforementioned fix. I’ll explain why the fix affects this usage below.

  1. The keyword signature used to be format_string(template, *positional, **named). The template argument was a normal argument that could be used both as a positional argument like Format String the template and as a named argument like Format String template=the template.
  2. Because the keyword accepted free named-arguments (**named), any argument with an equal sign was considered a named argument. Thus if the template contained = like in Format String some=content, it was considered to be a named argument some with a value content.
  3. A workaround was escaping the equal sign like Format Sting some\=content. It worked but not everyone knew about escaping and it was somewhat annoying in general.
  4. To avoid the need for escaping, the signature was changed to format_string(template, /, *positional, **named). The / in the signature makes template a positional-only argument that can be used only like Format String the template. Using it like Format String template=the template isn’t an error, but it is considered to mean that your template is the literal value template=the template.

It’s unfortunate that the fix causes this problem, but I still consider it more important that you don’t need to escape possible equal signs that you cannot use the template= prefix. Luckily the version without the prefix works also with older Robot versions, so you can simply remove it.

2 Likes