How to hit an API in Selenium IDE - selenium-ide

I'm testing front end using Selenium IDE, and I want to hit some api to generate test data such as Test Email address and password, before actually starting test.
I want to first hit API and store it's response into some variable which I can use it later in UI flow.

I've found solution like this:-
Use command "Execute Script" to execute Javascript code under currently opened Browser window. Here is what documentation says:
Executes a snippet of JavaScript in the context of the currently selected frame or window. The script fragment will be executed as the body of an anonymous function. To store the return value, use the 'return' keyword and provide a variable name in the value input field.
Arguments:
script - The JavaScript snippet to run.
variable name - The name of a variable without brackets."
Hence, in order to hit some api, we can write code like this:-
var request = new XMLHttpRequest();
request.open('GET', 'https://google.com', false);
request.send(null);
return request.responseText;

Related

how to get dictionary value from webrequest using sharepoint designer

I am trying to retrieve a value from a HTTP web service call in sharepoint designer. This should be simple. the Rest query is simple, and always returns only a single value:
https://Site.sharepoint.com/sites/aSiteName/_api/web/lists/getByTitle('MyListTitle')/items/?$select=Title&$top=1
In the Sharepoint Designer workflow, I'm setting the required Accept and Content-type header to the value of "application/json;odata=verbose
I am unable to get the value of the "Title" field that is returned by the call.
when I execute the REST query in the browser, I get the following data returned:
{"d":{"results":[{"__metadata":{"id":"af9697fe-9340-4bb5-9c75-e43e1fe20d30","uri":"https://site.sharepoint.com/sites/aSiteName/_api/Web/Lists(guid'6228d484-4250-455c-904d-6b7096fee573')/Items(5)","etag":"\"1\"","type":"SP.Data.MyListName"},"Title":"John Doe"}]}}
I've tried dozens of variations of the dictionary 'query', but they always return blank.
I'm using the 'get an item from a dictionary' action in SP Designer, using item name or path values like:
d/results(0)/Title
d/Title
d/results/Title
and literally dozens of other variations - but it always returns blank.
I'm writing the raw response from the webRequest to the list for debugging, and it shows the value like this:
{"odata.metadata":"https:\/\/site.sharepoint.com\/sites\/aSiteName\/_api\/$metadata#SP.ListData.MyListTitle&$select=Title","value":[{"odata.type":"SP.Data.MyListTitle","odata.id":"616ed0ed-ef1d-405b-8ea5-2682d9662b0a","odata.etag":"\"1\"","odata.editLink":"Web\/Lists(guid'6228d484-4250-455c-904d-6b7096fee573')\/Items(5)","Title":"John Doe"}]}
I must be doing something simple that is wrong?
Using "d/results(0)/Title" is right. Check the steps in article below to create a workflow.
CALLING THE SHAREPOINT 2013 REST API FROM A SHAREPOINT DESIGNER WORKFLOW
It working fine in my test workflow.
I faced the exact same issue. In my case the reason was that in the API call, the header was not set properly.
As you would have noticed many times, that if you type the variables inline when creating the "Call Http Web service" action, those might not get set properly. The surest way is to open the properties and set from there. In my case when i opened the properties i found that RequestHeaders was not set. Once i set it from there, i got the desired results.
Hope this helps to someone in future, this question being unanswered till now!!
tried dump those json called from sharepoint workflow into a list. Sometimes you'll get a different format than when you called that from browser. I experienced this issue when calling API projectserver (project online). When I called it using servistate (chrome extension) it returns d/results, but when I dump the value into the list I got value and yet I used same request header value.

Checking if an element is present in protractor

I have a protractor test that expects a certain panel to be NOT PRESENT after login. My code is below, but every time it is executed, protractor hangs and then fails later on.
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('The team overlay page should not be present when another user logs in.', function() {
loginPage.login(user.username, user.password);
expect(element(by.css('div.panel#myPanel')).isPresent()).toBe(false);
});
I also tried using .count() but it also does the same thing. Same error as above.
expect(element.all(by.css('div.panel#myPanel')).count()).toBe(0);
You could try waiting for the element by allowing the browser to fully load with some of the following:
browser.driver.sleep(time in milliseconds)
browser.waitForAngular()
You could increase the timeout interval:
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000
Otherwise:
Make sure your locator via css is working correctly (i.e, test it when the panel should be present), and make sure the webpage you are trying to access supports Angular. My bet is there is something incorrect with the format of your locator, as I don't see what else could be an issue.

How to retrieve specific profile variables from Watson's Dialog service via the watson-developer-cloud library

When retrieving profile variables from Watson's Dialog service, there is a parameter called name which allows you to control which variables are retrieved. If this parameter is blank, all variables that are associated with the specified client_id are returned. Otherwise, only the specified variables in name are returned.
I finally figured out how to specify more than one variable name on a direct GET to the REST API (give them all the same name, like &name=var1&name=var2), but I can't figure out how to do this via the watson-developer-cloud library. It seems that no matter how I specify names in the dialog.getProfile() function call, it always returns all of the variables.
Can someone tell me how to do this? I don't want to fetch them all every time and then search them for the one I want.
There was a bug in the library that was preventing name from being sent to the service.
Please update the library by doing
npm install watson-developer-cloud
And try with the example below
var params = {
dialog_id: '<dialog id here>',
client_id: '<client id here>',
name: ['var1', 'var2']
};
dialog.getProfile(params, function(err, response){
console.log(response)
});

Client context validation of data

As for tracking in AEM I am using CQ_Analytics for a scenario. We have a requirement like, I have to capture a value called "sort type" which is on the page when a user clicks on a button on that page and store it in ClientContext. I have written the below Javascript function which accepts a name argument. Using some code I am able to get hold of sort type value and passing it to the below function. Now my query is, how do I validate whether the name variable is assigned to the Client Context???
I have kept an alert statement and tried checking with multiple combinations but I am unable to figure out what is the correct way to conclude that my name value has been assigned to Client Context or not. Please help with my query.
function myFunction(name) {
CQ_Analytics.record({event: 'sorttype',
values: {'sortSelectedOption': name },
componentPath: '<%=resource.getResourceType()%>'
});
alert(CQ_Analytics.record.sorttype.sortSelectedOption);
}
You can see this post how to make your custom client context and how to store your data. http://blogs.adobe.com/aemtutorials/2013/07/24/customize-the-client-context/
After you create your client context, you have in the example CQ_Analytics.CustomStoreMgr.setTraitValue function that will save your parameter into client context.

Making a POST request in Selenium without filling a form?

I have an application A that should handle a form submit made with POST method. The actual form, that initiates the request, is in totally separate application B. I am testing application A using Selenium, and I like to write a test case for form submit handling.
How to do this? Can this be done in Selenium at all? Application A does not have a form that can initiate this request.
Note, that the request must use POST, otherwise I could just use WebDriver.get(url) method.
With selenium you can execute arbitrary Javascript including programmatically submit a form.
Simplest JS execution with Selenium Java:
if (driver instanceof JavascriptExecutor) {
System.out.println(((JavascriptExecutor) driver).executeScript("prompt('enter text...');"));
}
and with Javascript you can create a POST request, set the required parameters and HTTP headers, and submit it.
// Javascript example of a POST request
var xhr = new XMLHttpRequest();
// false as 3rd argument will forces synchronous processing
xhr.open('POST', 'http://httpbin.org/post', false);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('login=test&password=test');
alert(xhr.response);
In modern bleeding edge browsers you can also use fetch().
If you need to pass over to selenium the response text then instead of alert(this.responseText) use return this.responseText or return this.response and assign to a variable the result of execute_script (or execute_async_script) (if using python). For java that will be executeScript() or executeAsyncScript() correspondingly.
Here is a full example for python:
from selenium import webdriver
driver = webdriver.Chrome()
js = '''var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', false);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('login=test&password=test');
return xhr.response;'''
result = driver.execute_script(js);
result will contain the return value of your JavaScript provided that the js code is synchronous. Setting false as the third argument to xhr.open(..) forces the request to be synchronous. Setting the 3rd arg to true or omitting it will make the request asynchronous.
❗️ If you are calling asynchronous js code then make sure that instead of execute_script you use execute_async_script or otherwise the call won't return anything!
NOTE: If you need to pass string arguments to the javascript make sure you always escape them using json.dumps(myString) or otherwise your js will break when the string contains single or double quotes or other tricky characters.
I don't think that's possible using Selenium. There isn't a way to create a POST request out of nothing using a web browser, and Selenium works by manipulating web browsers. I'd suggest you use a HTTP library to send the POST request instead, and run that alongside your Selenium tests. (What language/testing framework are you using?)
The easiest way I found is making an intermediary page solely for the purposes of submitting a POST request. Have selenium open the page, submit the form, and then get the source of the final page.
from selenium import webdriver
html='<html><head><title>test</title></head><body><form action="yoursite.com/postlocation" method="post" id="formid"><input type="hidden" name="firstName" id="firstName" value="Bob"><input type="hidden" name="lastName" id="lastName" value="Boberson"><input type="submit" id="inputbox"></form></body></html>'
htmlfile='/tmp/temp.html'
try:
with open(htmlfile, "w") as text_file:
text_file.write(html)
except:
print('Unable to create temporary HTML file')
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.get('file://'+htmlfile)
driver.find_element_by_id('inputbox').click();
#wait for form to submit and finish loading page
wait = WebDriverWait(driver, 30)
response=driver.page_source