Protractor: sessionStorage variables - html

How would I get the value of a sessionStorage variable in protractor? I tried:
browser.executeScript('sessionStorage.getItem("login");');
but that returns null. Using sessionStorage.getItem() without browser.executeScript() returns an undefined for sessionStorage.

figured it out.
browser.executeScript("return window.sessionStorage.getItem('login');");

Try browser.driver.executeScript instead of browser.executeScript
i.e.
browser.driver.executeScript('sessionStorage.getItem("login");');
Also confirm manually that your javascript expression sessionStorage.getItem("login"); works fine by using the browser developer tools.
Depending on your app and the steps you are doing to get there, it may be requesting the session storage item too soon. If the browser.driver.executeScript doesn't fix your problem try adding a browser.sleep(4000); right before the executeScript to find out if this is a timing issue.
Note executeScript returns a webdriver promise so unless you are wrapping that in an expect you may need this:
browser.sleep(2000);
browser.driver.executeScript('sessionStorage.getItem("login");').then(function(retValue) {
console.log(retValue);
});

This is not quite right. It should be...
browser.driver.executeScript('return window.sessionStorage.getItem("login");').then(function (retVal) {
console.log(retVal);
});

Related

DataVizExtention: issue with clearing viewables while a sprite is selected

In my code, I have this workflow:
When user wants to see some things, add Sprites using 'DataVizCore.addViewables()'
Use 'viewer.addEventListener(DataVizCore.MOUSE_CLICK, onDotClick)' to show info bubble
When user wants to show other things, call 'DataVizCore.removeAllViewables()' to clear Sprites
Repeat from step 1
This sequence works OK except in one situation.
If a sprite was selected (by clicking on it) before removeAllViewables() is called, I don't get MOUSE_CLICK event for newly added Sprites. In browser console, I see following error is thrown.
CustomViewables.js:318 Uncaught TypeError: Cannot read property 'style' of undefined at ViewableData.getViewableUV (developer.api.autodesk.com/modelderivative/v2/viewers/7.*/extensions/DataVisualization/DataVisualization.js:454)
As a workaround, I added 'event.hasStopped = true' to click event handler to prevent Sprite getting selected internally. That seems to work.
This seems like a bug in DataVizExtension to me. Or, my workflow is wrong?
Thanks
Bandu
Bandu. Thanks for the detailed steps to reproduce this issue. I tried with v7.46.0 version of the DataVisualization.js (latest as of my message) but was not seeing the same issue. I'd be curious if you are using this same version of the Forge Viewer (you can figure that out by looking at the viewer3D.js fetched under the Network tab of Chrome DevTools).
Setting event.hasStopped = true works because it internally avoided the code path calls into getViewableUV that threw the exception, but the flag is meant for other use cases (e.g. overriding default sprite selection behavior).
In any case, I've just tweaked our internal code to make use-cases like yours more robust. The changes will be released with the upcoming v7.47.0. Thank you for your feedback 🙂

WebdriverIO waitfor methods don't work as expected

I am working on a set of webdriverIO tests that use a lot of pauses. To make the framework more robust I want to get rid of the pauses and introduce waitfor statements
I have looked through some walkthroughs, and most of them suggest something in the line of this:
var decrease = browser.$("//*[#id='somebutton");
decrease.waitForExist(5000)
decrease.click()
This doesn't work in 90% of the times however, returning the error message:
An element could not be located on the page using the given search parameters ("//*[#id='somebutton'"). (pretty much the same message I get when I remove the wait altogether)
I have tried both waitForExist and waitForVisible without success
I have played around a but, and found out that the following way does work:
browser.$("//*[#id='somebutton").waitForVisible(5000);
browser.$("//*[#id='somebutton").click()
I am not fond of this solution though, because it requires replication of the locator, which will make support harder in the future.
Can anyone shed some light on why the first option might not be working for me?
This should do the trick:
var selector = "//*[#id='somebutton";
browser.waitForExist(selector, 5000);
browser.click(selector);
Also, an example in the api docs shows it being done like this. Notice they left off the browser. portion.
var notification = $('.notification');
notification.waitForExist(5000);
Perhaps that is your issue? Both ways should work though.
One last thing, you don't have to use the xpath for this element if you don't absolutely have to. It's easier to just use the css selector for id.
var decrease = $('#somebutton');

How do you print the content (attributes) of a Polymer Object?

I'm a bit amazed I haven't been able to find an explanation for how to do this as it seems like it's fairly elemental to debugging, but I can't find anywhere how to print the attributes of an object in Polymer.
I'm learning Polymer and I keep running into situations where I have an object, but I have no idea what the attributes are of the object. (Ex. I print to the window, and I get [object Object]. I've found some explanations for how to print a list of the keys/attributes of an object (I know how to print the values for those keys if I know what they are), but I have no idea how to get the keys if I don't already know the format of my data. Every example presumes you already know what the attributes are.
I've seen solutions recommending adding a script like:
getKeys : function(o){
return Object.keys(o);
}
And then they recommend something like this:
<template is="dom-repeat" items="{{ item in obj | getKeys}}">
{{item}}
</template>
But I think they must work off maybe an earlier version of polymer. Most are from 2014-ish and I know the library has changed a lot since then.
This is the closest thing I get to an error with this code:
Polymer::Attributes: couldn`t decode Array as JSON
Here's an example post recommending this strategy. I understand I could dig deeper into the documentation and try to understand what response is supposed to be coming back, but I'm more curious what the general strategy is for this situation - I've multiple times wanted to check to see how polymer was modeling something vs how I thought it was.
The post you mention recommends a method that is no longer possible with post-1.0 Polymer, which does not support that syntax of filtering/pipes (as of the current release, 1.5.0).
You could use DevTools to select the Polymer element and then run console.dir($0). This works in the following browsers (and maybe older versions):
Chrome 50
Firefox 45
Safari 9.1
Opera 39
Chrome and Opera display all keys (even inherited ones from HTMLElement) in sorted order, so it can be tedious to scan through the long list of keys for a Polymer-specific property. However, Firefox and Safari list Polymer-specific keys first and then the inherited ones.
One workaround for Chrome/Opera is to use this snippet:
((o) => {
let obj = {};
Object.keys(o).sort().forEach((x) => {
obj[x] = o[x];
});
console.dir(obj);
})($0);
Here's a codepen that logs the attributes of a paper-button. You don't need to click the button. Open the browser's console log (not the Codepen console) to see something like the screenshot below. You can expand the fields in the console log to see the attributes of the Polymer object.
The solution I have been using is the following:
Place a button somewhere on the visible page.
When that button is tapped, print the object to the console.
my-element.html
<button on-tap="show">Click here to see user</button>
...
show: function() {
console.log('user', this.user);
},
...
You can also use console.dir() as follows.
<my-element id="foo"></my-element>
...
bar: function() {
console.dir( this.$.foo );
}

React-Router - componentDidMount not called when navigating to URL

I'm a little stumped on this one. I defined a route called classes/:id. When navigating to that route in the app, the componentDidMount() is called. However, when reloading the page or copying and pasting the URL the page completely loads, but the componentDidMount() method is not called at all.
From what I have read, the reason is because the same component mounted even though the page is being reloaded which is why the lifecycle method does ever get fired off.
What are some ways to handle this? Your help is greatly appreciated. Thanks!
componentDidMount will not be called again if you are already at a classes/:id route. You'll probably want to do something along the lines of:
componentDidUpdate(prevProps) {
if (this.props.id !== prevProps.id) {
// fetch or other component tasks necessary for rendering
}
}
I try to avoid any mixins (see willTransitionTo), as they are considered harmful.
Although componentDidMount does not fire when changing routes for the same component, componentWillUpdate and componentWillReceiveProps do.
From there, you can detect parameter changes, and can fire your actions accordingly.
the componentWillReceiveProps,componentDidUpdate lifecycle will receive the new props and then setState to change state to trigger render method.
I just dealt with this exact issue, took me a while to figure out the problem. I'm sure everything previously suggested works great as a solution. How I solved the problem was a bit different though. My componentDidMount function was essentially just providing a state update, so I just moved the functionality directly into the state and bypassed componentDidMount.
Honestly, I'm not sure if this is best practice or not (very happy for feedback if it isn't), but it's running efficiently and works great so far.

Backbone-support nested view and Chrome

It's the first time I use backbone-support to handle zombie views.
Before introducing it, I did not have the following problem:
this.$el.append(this.template());
// this view fills up a select with options taken from a web services
this.renderChildInto(new App.view.ResourcesView({name: "idActivityDesc", url: "/wfc-services/resources/activities"}), "#divIdActivityDesc");
// population of the forms elements according to the loaded model
this.populateSelectElements();
this.populateTextElements();
if(this.model.get('completed')) {
this.$("#active").removeAttr("disabled");
}
this.delegateEvents(this.events);
return this;
With Firefox it's all working fine. If the model is empty the select elements are going to be set up with default elements. In my case is selectedIndex to -1.
Going in debug inside the view everything seems fine. I have the problem when the view is going to be happened to the parent via the method renderChildInto. The dom is fine, but without the changes derived from the populateSelectElements() if the model is empty. If it's not empty I have no problem and the view is working fine.
I'm really puzzled about it because before the return this; statement, even in Chrome/Chromium I see the selectedIndex to -1. But in the final rendered view on the browser I see the select having selectedIndex to 0.
In the composite_view.js the called code is:
renderChild: function(view) {
view.render();
this.children.push(view);
view.parent = this;
},
renderChildInto: function(view, container) {
this.renderChild(view);
this.$(container).html(view.el);
},
Here's the end of this story.
I found from many sources, including stackoverflow, that it is possible to use selectedIndex to -1.
I'm not a frontend developer and I do not have so much experience with browser compatibility so I found the help I needed from a colleague of mine that is expert in this thing and basically suggested me that this type of usage of selectedIndex was really weird.
He suggested me to use a default option element with value to "-" or whatever was compliant with the domain to define an empty element.
Worked like a charm and since we actually did a good job in the design we had just to change the selectedIndex from -1 to 0.