# How To create keywords for only xapth changing test cases

**URL:** <https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709>\
**Category:** SeleniumLibrary\
**Created:** [15 May 2023 14:37 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709 "2023-05-15T14:37:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [15 May 2023 14:37 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/1 "2023-05-15T14:37:30Z")

</div>

Currently I’m using having code as:

```python
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath}
        ${webelements}= Run Keyword If ${xpath_available} Get Webelements ${xpath}
        @{element_list} Create List 
        IF ${xpath_available}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${key}=${element_list}
    END

```

this code repeats for every test case only the xpath will vary for each time so i want to use keywords instead of writing this code again and again and also instead of creating the list i want to add element one by one when it is iterating in for loop and add to the dictionary can anyone guide how can i acheive expected result

---

<div class="post-metadata">

**Author:** ![damies13](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/damies13/32/623_2.png) [@damies13](https://forum.robotframework.org/u/damies13)\
**Post date:** [15 May 2023 15:07 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/2 "2023-05-15T15:07:33Z")

</div>

Hi Leo,

[User keyword syntax](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#toc-entry-330)

The `[Arguments]` setting and `RETURN` are what you’re after, then do something like this (warning completely untested and typed after 1am 😂):

```python
***Test Cases***
Test Case 001
    ${my_dictionary_data_1}= Parse Xpath To Dictionary ${xpath1}

Test Case 002
    ${my_dictionary_data_2}= Parse Xpath To Dictionary ${xpath2}

***Keywords***
Parse Xpath To Dictionary
    [Arguments] ${xpath}
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath}
        ${webelements}= Run Keyword If ${xpath_available} Get Webelements ${xpath}
        @{element_list} Create List 
        IF ${xpath_available}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${key}=${element_list}
    END
    RETURN ${dictionary_data}

```

Dave.

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [15 May 2023 19:32 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/3 "2023-05-15T19:32:57Z")

</div>

@damies13 Thanks for your efforts 😀

Actually, I forgot to add some lines

I got error as ${column\_index} not found when i used above code actually I want to make keyword which is useful even if the xpath changes. I will have xpath which will have ${column\_index} somewhere in the xpath for example:

```python
#ex1
${element_xpath}= //div[@class='abc']\[${column_index}]/div[1]/div[2]  
#ex2
${element_xpath}= //div[@class='abc']/div[1]/div[2]\[${column_index}] 

```

somewhere in my xpath I’ll have ${column\_index}

So only xpath will be different in other test cases so can we create Keyword which will work even if the xpath is different but it contains ${column\_index} somewhere in xpath can you help me out I’m stuck in this my code looks repetative and i want to use keyword instead of that

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 08:18 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/4 "2023-05-16T08:18:46Z")

</div>

@_daryl @HelioGuilherme66 @damies13 @NikosKoul  
Sorry to tag you all but anyone can help I’m stuck in this tried all things but didnt get solution

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 08:40 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/5 "2023-05-16T08:40:27Z")

</div>

Might be worth sharing your current code snippet for that keyword etc… (id imagine you have adjusted since the og post), as the:

> _I got error as ${column\_index} not found_

Sounds like that variable hasn’t been set/initialized, and you are using ${column\_index} to that end for which that error is being thrown, I’d imagine the full error is just that _“Variable ${column\_index} not found”_ but hard to really say whats happening without seeing the latest code snippet.

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 08:55 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/6 "2023-05-16T08:55:34Z")

</div>

\*\*\* Test Cases \*\*\*  
Test Case 001  
${my\_dictionary\_data\_1}= Parse Xpath To Dictionary /div[@class=‘abc’][${column\_index}]/div[1]/div[2]

Test Case 002  
${my\_dictionary\_data\_2}= Parse Xpath To Dictionary ${xpath}${columns}[${column\_index}]

```python
Parse Xpath To Dictionary
    [Arguments] ${xpath}
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${xpath_with_index}= Set Variable If '${xpath}' contains '${column_index}' '${xpath}' '${xpath}'.replace('${column_index}', str(${column_index}))
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}
        ${element_list}= Create List
        IF ${xpath_available}
            ${webelements}= Get Webelements ${xpath_with_index}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${column_index}=${element_list}
    END
    RETURN ${dictionary_data}

```

For this code _Variable ${column\_index} not found_ error is showing and in above code xpath will be diffrent for different test cases but xpath will have ${column\_index} somewhere . so I want to replace ${column\_index} with the value iterating through the xpath i.e(FOR ${column\_index} IN RANGE 1 ${column\_Count}+1)

So I want to use Keyword in test cases rather than repeating same code again and again only xpath of the keyword will be diffrent

---

<div class="post-metadata">

**Author:** ![HelioGuilherme66](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/helioguilherme66/32/34_2.png) [@HelioGuilherme66](https://forum.robotframework.org/u/HelioGuilherme66)\
**Post date:** [16 May 2023 09:19 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/7 "2023-05-16T09:19:10Z")

</div>

> [@mk111](#):
>
> `[Arguments] ${xpath}`

You need to have `${column_index}` here and build the xpath expression inside the keyword. When you pass it like you are doing, you are passing the values, no variables by reference.

Other solution, but a bad practice one, is to declare `${column_index}` as a global/test suite/test case/ variable.

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 09:31 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/8 "2023-05-16T09:31:04Z")

</div>

Thanks, @HelioGuilherme66 beat us to it

As an alternative🤢 , if @mk111 were to keep it as it was, and replace the **${column\_index}** from within their XPath variables/passed xpaths with just **column\_index** (no $ or { } ) and then replace the first line after the FOR starting statement with the below in the:

`${xpath}= Replace String ${xpath} column_index ${col_index}`

Then that should also work, if they wanted to check if contains them prior to replacing the column\_index with the FOR value, then do the below or an equivalent:

`${xpath_contains_index}= Evaluate "column_index" in "${xpath}"`

Then they could handle cases where the XPath doesn’t hold the temp column\_index and possibly BREAK/CONTINUE if it wasn’t to exist depending on their handling, but there really are so many ways.

**EDIT:**  
Figured it best to provide what changes to the snippet if you weren’t to handle it the way @HelioGuilherme66 proposed

so replace these two:

```
${xpath_with_index}= Set Variable If '${xpath}' contains '${column_index}' '${xpath}' '${xpath}'.replace('${column_index}', str(${column_index}))
${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}

```

with:

```
   ${xpath_available}= Set Variable ${False} 
   ${contains_column_index}= Evaluate "column_index" in "${xpath}"
   IF ${contains_column_index}
       ${xpath_with_index}= Replace String ${xpath} column_index ${column_index}
       ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}
       # rest of code here... for what's relevant...ofc
   ELSE    
      # Handle cases however when XPath doesn't hold temp column_index BREAK/CONTINUE/FAIL etc...
   END

```

Calling the keyword would look like this (see column\_index with no $ or { } ):

```
${my_dictionary_data_1}= Parse Xpath To Dictionary /div[@class=‘abc’][column_index]/div[1]/div[2]

```

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 14:10 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/9 "2023-05-16T14:10:44Z")

</div>

Im little bit confuse how to use this in code can you please show if possible

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 14:40 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/10 "2023-05-16T14:40:46Z")

</div>

@_daryl I’ll always have “column\_index” somewhere in xpath currently I used solution as:

```python
***Test Cases***
Test Case 001
    ${my_dictionary_data_1}= Parse Xpath To Dictionary /div[@class='abc'][column_index]/div[1]/div[2]    

Test Case 002
    ${my_dictionary_data_2}= Parse Xpath To Dictionary ${xpath}${columns}[column_index]    
***Keywords***
Parse Xpath To Dictionary
    [Arguments] ${xpath} ${column_index}
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${xpath}= Replace String ${xpath} column_index ${column_index} 
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}
        ${element_list}= Create List
        IF ${xpath_available}
            ${webelements}= Get Webelements ${xpath_with_index}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${column_index}=${element_list}
    END
    RETURN ${dictionary_data}

```

By using above code I got error for line

```python
Replace String ${xpath} column_index ${column_index}

```

TypeError: replace() argument 2 must be str,not int

Can you please guide @_daryl @HelioGuilherme66 @damies13

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 14:58 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/11 "2023-05-16T14:58:57Z")

</div>

Just to keep it simple:

```python
${str_col_index}= Convert To String ${column_index}
Replace String ${xpath} column_index ${str_col_index}

```

If interested… you can log the type, which can be useful if in doubt but the message in your case is as it reads, is saying your passing and int not a string, and also looking at documentation is also very useful:

```python
${type}= Evaluate type($variable). __name__
${type}= Evaluate type($variable)

```

The top one will return the name property ‘int’, ‘string’ etc… and the bottom one you’ll see  
\<class ‘type’\> type being int, string etc…

in addition, you can use the isinstance($variable, int) and that will return true or false but less relevant here, but nice to know.

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 16:23 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/12 "2023-05-16T16:23:50Z")

</div>

@_daryl @HelioGuilherme66 @damies13 Thank you for the solution It helped me a lot now my code runs successfully

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 22:36 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/13 "2023-05-16T22:36:03Z")

</div>

Hellow @_daryl Sorry to disturb you again and again but I have one major concern  
The xpath is taking only 1 index and for other it is continuing with the same xpath I tried alot of things but not able to figure it out

```python
/div[@class='abc'][column_index]/div[1]/div[2]  
/div[@class='abc'][1]/div[1]/div[2]

```

execution continuing with same xpath but it is expected that column\_index will change IN RANGE of ${column\_Count}  
Can you please help?

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 23:05 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/14 "2023-05-16T23:05:58Z")

</div>

Looking at what you last shared as a snippet, the replace string is assigned to ${xpath} but you don’t use it at all in the statements thereafter, see these two lines taken from the last shared snippet:

```
 ${xpath}= Replace String ${xpath} column_index ${column_index} 
 ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}

```

So that wouldn’t work as the ${xpath\_with\_index} doesn’t exist, but _I’d guess_ and say if you shared you’re latest snippet it would differ slightly, and at an assumption, it will show like the below or somewhat similar:

```
${xpath}= Replace String ${xpath} column_index ${column_index} 
${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath}

```

If my assumption is right, and based on your comment… that what you will need to do/ensure is to change those two lines to:

```
${xpath_with_index}= Replace String ${xpath} column_index ${column_index} 
${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}

```

This is because the replace has assigned back to the _ **original variable ${xpath}** _ so it will no longer holds the [column\_index] part in its original state and will hold [1] in its place, so on the second iteration the replace isn’t actually replacing anything, hence why it’s only ever showing [1]

But purely assumptions based on not knowing how the current block sits, and looking above the last snippet you shared would have thrown an error at that point as the variable ${xpath\_with\_index} never existed, but it had likely fallen over on the calling keyword as you had two arguments expected to be passed, where one only showed to be passed (id imagine you have adjusted this already).

But ultimately, if that is not the problem then sharing the code block would be very helpful.

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 23:19 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/15 "2023-05-16T23:19:58Z")

</div>

> [@mk111](#):
>
> but I have one major concern  
> The xpath is taking only 1 index and for other it is continuing with the same xpath I tried alot of things but not able to figure it out
> 
> ```python
> /div[@class='abc'][column_index]/div[1]/div[2]  
> /div[@class='abc'][1]/div[1]/div[2]
> 
> ```
> 
> execution continuing with same xpath but it is expected that column\_index will change IN RANGE of ${column\_Count}  
> Can you please help?

@_daryl thanks and sorry if I look like demanding but can you please show in code what changes i have to make to so that the code will work fine I’m new to robot framework and literally working on this code since last month

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 23:20 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/16 "2023-05-16T23:20:53Z")

</div>

You able to share your current code block?

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 23:28 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/17 "2023-05-16T23:28:57Z")

</div>

```python
***Test Cases***
Test Case 001
    ${my_dictionary_data_1}= Parse Xpath To Dictionary /div[@class='abc'][column_index]/div[1]/div[2]    

Test Case 002
    ${my_dictionary_data_2}= Parse Xpath To Dictionary ${xpath}${columns}[column_index]    
***Keywords***
Parse Xpath To Dictionary
    [Arguments] ${xpath}    
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${str_col_index}= Convert To String ${column_index}
        ${xpath}= Replace String ${xpath} column_index ${str_col_index} 
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}
        ${element_list}= Create List
        IF ${xpath_available}
            ${webelements}= Get Webelements ${xpath_with_index}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${column_index}=${element_list}
    END
    RETURN ${dictionary_data}

```

This is my latest snippet I also tried by ${column\_index} as second argument and used in test case also but it didnt worked

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 23:32 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/18 "2023-05-16T23:32:37Z")

</div>

```
***Keywords***
Parse Xpath To Dictionary
    [Arguments] ${xpath}    
    ${dictionary_data}= Create Dictionary
    ${column_Count}= Get Element Count ${total_columns}
   
    FOR ${column_index} IN RANGE 1 ${column_Count}+1
        ${str_col_index}= Convert To String ${column_index}
        ${xpath_with_index}= Replace String ${xpath} column_index ${str_col_index} 
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath_with_index}
        ${element_list}= Create List
        IF ${xpath_available}
            ${webelements}= Get Webelements ${xpath_with_index}
            FOR ${element} IN @{webelement}
                ${element_text}= Get Text ${element}
                Append To List ${element_list} ${element_text}
            END
        END
        Set To Dictionary ${dictionary_data} ${column_index}=${element_list}
    END
    RETURN ${dictionary_data}

```

That should now replace the column\_index and not stay sat at [1]

---

<div class="post-metadata">

**Author:** ![mk111](https://avatars.discourse-cdn.com/v4/letter/m/9de053/32.png) [@mk111](https://forum.robotframework.org/u/mk111)\
**Post date:** [16 May 2023 23:32 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/19 "2023-05-16T23:32:58Z")

</div>

```python
${xpath}= Replace String ${xpath} column_index ${str_col_index} 
        ${xpath_available}= Run Keyword And Ignore Status Element Should Be Visible ${xpath}

```

little correction this is used in my snippet

---

<div class="post-metadata">

**Author:** ![\_daryl](https://avatars.discourse-cdn.com/v4/letter/_/45deac/32.png) [@\_daryl](https://forum.robotframework.org/u/_daryl)\
**Post date:** [16 May 2023 23:36 UTC](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709/20 "2023-05-16T23:36:01Z")

</div>

That’s fine and looks to be as per my assumption, if you replace what I shared with your current then it should increment, as the original XPath was being changed, so it just needs assigning to a new variable, as on the second loop and thereafter it can’t replace the column\_index as it no longer exists in the ${xpath} for that reason, so it will always hold [1] in its place.

[Next page](https://forum.robotframework.org/t/how-to-create-keywords-for-only-xapth-changing-test-cases/5709.md?page=2)
