Karate Multi-url access in a single scenario - karate

I want to access multiple url in a single scenario.
When the url is defined in Background and the another url is used in Scenario, the url is changed.
If I use path, the behavior is not expected.
Can it fix url in Background?
Feature: examples
Background:
* url 'https://jsonplaceholder.typicode.com'
Scenario: get all users and then get the first user by id
Given path 'users'
When method get
Then status 200
Given url 'https://api.github.com/search/repositories'
And param q = 'intuit/karate'
When method get
Then status 200
# The expected behavior is accessed to 'https://jsonplaceholder.typicode.com/users'.
# But the accual behavior is accessed to 'https://api.github.com/search/repositories/users'.
Given path 'users'
When method get
Then status 200

No, but if you move Given url 'https://api.github.com/search/repositories' to a second Scenario: it will work fine.
This is a deliberate design. Look at the hello world example. It makes 2 calls, but the url is mentioned only once, because the second call is just a path addition. This is the typical REST pattern.
So if you need to really do a different API call, you have to use the full url:
Background:
* def baseUrl = 'https://jsonplaceholder.typicode.com'
Scenario: get all users and then get the first user by id
Given url baseUrl
And path 'users'
When method get
Then status 200
Given url 'https://api.github.com/search/repositories'
And param q = 'intuit/karate'
When method get
Then status 200
Given url baseUrl
And path 'users'
When method get
Then status 200

Related

Retry until with dynamic path or params [duplicate]

I have a use-case where I need to first call an API to get a list of ID's. From this response a random ID is chosen. Next I call a 2nd API which uses the random ID as a component in the path.
It's possible the 2nd API call can return an empty response, therefore I want to utilize retry until but use a different random ID in the path per retry iteration.
I've tried a couple of things:
First "in-lining" the JS function in the path to get a random ID:
Given path firstPart, myGetRandomId(idList), lastPart
And retry until response.length > 1
Second, tried putting the JS function in a Examples: as part of a Scenario Outline:
Given path firstPart, <ID>, lastPart
And retry until response.length > 1
Examples:
| ID |
| myGetRandomId(idList) |
The general issue I can't figure out is how to get the JS function to evaluate in either of this "in-line" kind of approaches.
And ideas/suggestions appreciated.
The way that the Karate retry until works is that it will re-play the request as-is and you can't modify it.
So you have to take a different approach. Use a JS loop. Look at this example in the demos:
https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/polling/polling.feature

How to dynamically create URL having path in between URL using Karate framework

I want to create a dynamic url using karate framework. lets assume URL I want to create is :
https://www.mars.com/mars/profile/{profileID}/line
In above URL {profileID} is path.
Currently I have written below feature file which is able to create the url however due using path keyword it encodes the url and add %0A after profile id.
https://www.mars.com/mars/profile/264%0A/line
Feature File:
#smoke
Scenario: Create a line score in existing profile
And def urlname = marsuri+ '/mars/profile/'
Given url urlname
Given path id + '/line'
Please let me know how can I create a URL with path in between URL without encoding it.
You are not using the path syntax correctly. Please read the documentation: https://github.com/intuit/karate#path
Make this change:
Given path id, 'line'
EDIT: please also see this answer: https://stackoverflow.com/a/54477346/143475
Actually that id variable wherever you are getting it from is having a new line at the end of the string, something like this "264\n" that is why it is getting encoded to 264%0A
If all you wanted to pass is "264" you have to remove the unwanted values before adding it to the path
Background:
* def removeNewLine = function(x){return x.replace("\n","")}
Scenario: Create a line score in existing profile
And def urlname = marsuri+ '/mars/profile/'
Given url urlname
* def id = removeNewLine(id)
Given path id + '/line'
If you can modify the data directly from the source where you are getting the id that would be great.

I want to pass the header value in methods

Scenario : I need to verify the logs response on server on the basis of Tracking-Id.
I had passed the tracking-id using 'header.js' file, here i define metod which get the unique UUID for every request and passed in header.
Now I need that header value to passed in some method to get logs only for specific Tracking-Id
Is there any way to achieve this in karate?
Yes, you can use karate.set('someVarName', uuidValue) in JS and then back in the feature you will be able to: * print someVarName.
EDIT: please see this commit for an example: link

Flask rewrite url

I'm doing a small project that pulls data from tmdb's API.
Right now I have a /tv view that takes an id and request the TV show associated with that id. It results in a url like example.com/tv/23521. Looking at tmdb's own site their URL structure seems to something like "id-slug-title". Regardless of what comes after the ID it still redirects you to the right page.
How is that done? It would seem that it takes in the URL, splits it at "-" and uses the first parameter as ID. I am not sure how to do that in Flask though. I was thinking of using before and after request methods, but I'm worried that will just make unnecessary API calls. In order to get the slug title, I would have to make at least one call with the ID to get the title and then slugify that title.
The route accepts both an id and a slug, where the slug is optional:
#app.route('/tv/<int:id>', defaults={'slug': None})
#app.route('/tv/<int:id>-<slug>')
def tv(id, slug):
# ...
Note that you don't have to do any splitting yourself; the route matches if there is an integer number followed by a dash and some more text, or if it is just a number.
Only the id parameter is needed to find the right page. The slug is simply checked against the 'canonical' and you are redirected if it doesn't match:
page = load_page(id)
if slug != page.slug:
return redirect(url_for('tv', id=id, slug=page.slug))
Don't recalculate the slug each time, just store that in the database. You'll have to load the page info anyway for you to be able to serve it.
You could put that behaviour in a decorator and pass in the loaded page data into the view:
#app.route('/tv/<int:id>', defaults={'slug': None})
#app.route('/tv/<int:id>-<slug>')
#tv_page
def tv(page):
# ...
with tv_page then handling the parameters:
from functools import wraps
def tv_page(view_func):
#wraps(view_func)
def wrapper(id, slug):
page = load_page(id)
if slug != page.slug:
return redirect(url_for('tv', id=id, slug=page.slug))
return view_func(page)
return wrapper

How to determine if URL exists using Sharepoint API?

How can I determine if my current full URL is existing?
Basically, I am doing a checking on all pages in a given site. The output of all pages is in XML. However, what if I deleted a page, I want to know if the URL is still existing or NOT so I can update the output.
Example:
Here is my url:
http://mySite.com/Pages/Page1.aspx
Given this URL, how can I determine if it still exists?
I tried to use SPWeb.OpenWeb but SpWeb.Exists always return a True value.