Feature
Postman added support for variables, authorization, pre-request and test scripts to collections.
(As of version 5.4.1 this exists at both the collection AND the folder level.)
Use case
Let's say I want to store a refresh token when the login endpoint is hit. My test script needs to create/update a COLLECTION variable, NOT a global or environment variable.
Once that refresh token is available to the collection, other tests and pre-request scripts, I would think there is a way to access them through an API similar to pm.environment or pm.globals. (pm.collection, for instance)
Question
I cannot find any documentation on how to access or modify those via pre-request scripts, or tests... Does anyone know how to do this? Maybe this hasn't been thought out completely, or not fully implemented, but I thought I would check with others for some help.
Temporary Solution
As a complete hack, I am storing the things I need as namespaced environment variables. It's not ideal (makes things kind of messy when working in other collections) but it works just fine.
Collection variables
You can access collection variables (and all variables) in the pre-request and test script sections using pm.variables.get("variableName").
However, you can only define and update collection variables by editing the collection details via modal.
Note: For your current solution using environment variables getting messy, remember you can always use pm.environment.set() to reset the value or pm.environment.unset() to clear it.
Postman v7.9.0 added support for new pm.collectionVariables, so you can update them on test scripts:
pm.collectionVariables.set("collection_variable", newValue);
https://github.com/postmanlabs/postman-app-support/issues/5053#issuecomment-542555156
Setting collection variables manually and then getting them
was always possible.
Setting collection variables in scripts and not just manually
became possible in version 7.9.0 which was released in October
2019.
As of writing this, there is still obsolete misinformation about it
out there - on the internet in general - but sadly also here
at Stack Overflow.
Although this question has already been correctly answered, I am adding this answer in an
attempt to clear up any remaining confusion.
A collection variable can be set in a script
To find out who is right and
who is wrong, I made a simple
little experiment.
Below I describe what I did.
You can replicate the exact same experiment yourself.
I have created a Postman collection named ManipCollVars.
(ManipulateCollectionVariables seemed a little too long.)
You can download and save it to your local drive from:
https://user.it.uu.se/%7Ehesc0353/postman/ManipCollVars.pm_coll.json.
Then - from your Postman desktop app (not the chrome extension) -
import ManipCollVars (Collections > Import > File >
Upload Files) as shown in the figure below.
(The dummy GET request is https://postman-echo.com/get.)
^ click to enlarge
The initial value of the collection variable CollectionVar
In the left pane, on the same line as ManipCollVars is displayed,
click on the ellipsis to the right (the three mini circles: •••), and
then Edit.
See the figure below.
Next click on the Variables tab.
Note that the CURRENT VALUE of CollectionVar is "Initial Value".
Run the dummy request and the Tests script
Click on the request ManipCollVars-Request, and then on its Tests
tab as shown in the figure below.
Focus on lines 7-11:
// Will now try to change `CollectionVar` to some new value:
pm.collectionVariables.set('CollectionVar', 'Some New Value');
// Then print the new value of `CollectionVar` to the console:
console.log(pm.collectionVariables.get('CollectionVar'));
// ^ Does CollectionVar contain "Initial Value" or "Some New Value"? ^
Click on the blue Send button, and then open the Console
in the bottom left corner as in the figure below.
Note how the value of the collection variable has changed from
"Initial Value" to "Some New Value". - Issue settled!
Double-checking the value of the collection variable
To double-check that the value has indeed changed, click once again on
the ellipsis (•••) next ManipCollVars > Edit > Variables.
Note that the CURRENT VALUE of CollectionVar is now
"Some New Value". - Confirmed!
^ click to enlarge
References
Correct answer to this question
Defining variables in scripts
Postman Quick Reference Guide: Collection variables
Using collection variables in scripts
Answer to "Using Collection Variables in Postman"
Postman: The Easy Way to Work with APIs
Related
I am currently using https://github.com/admc/wd/blob/master/doc/api.md Selenium web driver to test website. I want to simply to check if my view is on the top of the whole screen.
I have attempted to use isDisplay() and getLocationInView to serve such purpose.
However, they are either available as absolute position of the element or display in term of element and html page level, instead of actual view itself.
I also tried execute() eval() to run JavaScript to capture window then evaluation its axis value, since Selenium is running a real browser (Chrome).
i.e.
...execute("window", function(error, result) { console.log(result) };
...execute("console.log(window)", function(error, result) { console.log(result) };
...execute("return window", function(error, result) { console.log(result) };
However, I was only able to get null out of the result from these statement.
I think I must have missed a function (even though I read through their API doc more than 3 times).
I thought trigger JavaScript variable inside the testing browser, run a quick func to get axis value, and save it into a var is a viable solution.
However, I was not even able to find a working solution to just getting the window global var. (yes, after looked at all the relevant post indicate about executing js with selenium)
*Note and yes executeScript is no longer available, as least for the Selenium I am working with right now (latest version according to my package.json).
*Also important note:
I use wd.js as the web drive
https://github.com/admc/wd
Alllrighty. I found the solution! Its pretty straight forward. I think it was just because wd.js using promise chain at all time, so I am not able to output anything with just eval, but I have to add asserter. so following worked perfectly.
browser.eval("window.pageYOffset")
.should.eventually.equal('0')
.nodeify(done);
if you want to see what's the value in window.pageYOffset just fail it manually.
Take me two days to understand this thing. Hopefully it save your time as well.
I have run into an issue that I believe is rooted in the implementation of anchor tags in Rhino. Although I am utilizing env.js, I suspect perhaps I am not configuring something correctly.
In particular, my issue occurs while I am attempting to write unit tests against code written for an angularjs application. When I include angular.js (versions 1.2.1 to present), I get the following error:
TypeError: Cannot call method "charAt" of undefined
I am convinced the error is the result of this call to urlParsingNode.pathname since a console.log call reveals that the pathname object is undefined.
I traced the instantiation of the urlParsingNode to this line where we see that it is the result of a call to document.createElement("a"); Further down, we see that they set the href attribute in this line in hopes that the created anchor tag will utilize the browser to correctly parse the URL.
I have to believe I'm not the first to attempt JS unit testing for angular via Rhino, but thus far I've not successfully Googled myself to a solution. Any tips will be greatly appreciated.
Found it and fixed it. The pathname getter/setter simply was undefined for HTMLAnchorElement in env.js.
I submitted a pull request, but unfortunately the project looks all but abandoned. I also couldn't figure out how to build it out to a single file. It appears perhaps someone has taken it upon themselves to break it apart into require.js modules. Not a battle worth fighting for my use case.
So for anyone else who hits this issue, I have the code you need below. It belongs in the HTMLAnchorElement.prototype. In my copy of env.js 1.2, this prototype begins on line 8075. I added the following at line 8118.
get pathname() {
var uri = Envjs.urlsplit(this.href);
return uri.path;
},
set pathname(val) {
var uri = Envjs.urlsplit(this.href);
uri.path = val
this.href(uri.urlunsplit(uri));
},
FYI, my particular issue is resolved with this pull request.
After I installed and referenced the JSNLog package into my MVC project, I'm experiencing an error when ever I click a link.
For example,
Link
usually produce
Link
but after I start using the JSNLog, it now produce
Link
which will direct to a link
http://localhost:51745/jsnlog.logger?action=Bar&controller=Foo
which shows
Exception Details: System.NullReferenceException: Object reference not
set to an instance of an object.
I believe JSNLog is trying to send back a exception or log event back to the server whenever it has a chance to access the server.
Am I missing something to make this functional?
This bug existed when the original post was created, but it has been fixed a few version ago now (I am the author of JSNLog).
This is actually caused by the Ignore route they inject in App_Start, moving it into your routes collection manually fixes the issue. It happens because you don't manually define routes for the rest of the controllers, so .net tries to resolve to the first one it finds defined.
In App_Start\JSNLogConfig.cs take out
RouteTable.Routes.Insert(0, new Route("jsnlog.logger/{*pathInfo}", new StopRoutingHandler()));
In RouteConfig.cs add
routes.IgnoreRoute("jsnlog.logger/{*pathInfo}");
And all your other routes should start working fine.
When I use console.log("Some text output") in javascript in Visual Studio 2012 for Windows 8 metro programming where is the text being sent to? Where can I view it? I've got the "Output" panel up but I do not see the log text.
Am I not using the right function? Is there another function I must use to print to Output?
To actually see the JavaScript console select DEBUG > Windows > JavaScript Console in the Visual Studio menus. Then you can use the good old console.log() to write to it, but you can also use the related WinJS functions:
There is WinJS.log() to log something after creating the function with WinJS.Utilities.startLog():
WinJS.Utilities.startLog({type: "info", tags: "custom" });
WinJS.log("my message", "info", "custom");
Here's some additional information on the WinJS logging functions:
startLog(options): Configures a logger that writes messages containing the specified tags to the JavaScript console.
The options object must contain a type which is supposed to be one of error, warn, info or perf. Unless you want to capture all log entries, also add tags to the object containing a space-separated list of tags you want to be logged.
WinJS.log(message, tags, type): This function does not exist by default. However, it is created by your startLog() call. You could also create it manually but since you want logging to the console using startLog() is the way to go.
If you need to debug the application in a live environment, you can use a simple on-screen console.log replacement, which you can activate using the ~ key.
Source code here:
https://gist.github.com/4012355
You can also view the log through the EventViewer. Here are the steps to enable this:
Open Event Viewer
Navigate to Application and Services Log
Expand Microsoft/Windows/AppHost
Left click to select Admin
Right click Admin and then select View => Show Analytic and Debug Logs
I might be replying to an old post, or maybe you have discovered your way to serve your purpose, but I tried console.log() and WinJS.log() and the javascript console seem to return 'undefined' for both. Also, I made sure with 'debugger;' statement that that code was is executing. Now I am assuming here that you need logging for debugging purposes then what I would prefer to "print" to my screen now is:
<body>
<label id="lblMessage">test</label>
</body>
and then in JS :
function f(message) {
document.getElementById('lblMessage').innerText = message;
}
( and then, place a call to this function where needed - in my case it was, app.onactivated function)
This one's perhaps a duplicate of "variable not recognized inside contentscript" under the same section. I got part of my query solved there from the answer to that question. Yeah, I understand that
The content script context is entirely disconnected from the addon script context. Content scripts are run in the context of the document, while addon scripts aren't.
But does that mean we can never access a variable in the content script context in the addon script context? If by any means we could access them, please do let me know. My requirement needs objects to be sent as parameters to functions in another script(data/utilities.js) and possibly get the returned object. There was no difficuty in doing the former but am stuck with the latter cos of the aforementioned context problem. I am able to return the value from the content script context but unable to access the same in the addon context. Can anyone please help me out with a little example of this?
PS I could as well discussed it there but I read that I shouldn't as this ain't a discussion forum.
You cannot get direct access to variables in the content script from the addon script context directly. You can pass the variable back to the add-on from the content script using
self.port.emit('send-some-var', some_var)
You would then receive the variable's value in the add-on script by listening for the same event:
worker.port.on('send-some-var', function(data) { console.log(data) })
The main limitation however is that the data being passed through must be JSON-serializable, so you could not have a complex object with methods, etc. Only data.