$location.hash() - Not running rest of JS. Weird behavior? - angularjs

Trying to do a simple scroll to the top of my page when the user clicks the 'edit' button. For some reason, when I try to set the $location.hash, it will not run any code following it.
It will put the value into the console, and in the browser address bar, but nothing after.
If you click 'edit' again, (the location value will be in the address bar, i.e. - sitename.com/#/send#top), and the rest of my code will run as expected.
Any ideas what I am doing wrong?
scrollToLoc = function(loc) {
$location.hash(loc);
$anchorScroll();
console.log(loc);
};
$scope.doEdit = function(item) {
scrollToLoc('top');
$scope.request = item;
};

Related

PHP, Codeception, Firefox and new tab - how to?

I have a test for PHP project which opens a new tab by double-click. I test it in Firefox.
I am new to Codeception, but I've read and tried everything I've found with no luck.
I have a table which rows are spans. I want to double-click it and to check if correct page is open.
I try:
$i->scrollTo(['xpath' => '//span[text()="test"]']);
$i->doubleClick(['xpath' => '//span[text()="test"]']);
$i->waitForText("test text", 15);
$i->seeCurrentUrlMatches('~^/register/materials/view/\d+$~');
The issue is that doubleClick opens a requested page in new tab like this:
jumpTo: function(row) {
const link = document.createElement('a');
link.href = window.location.pathname + '/view/' + row.id;
link.setAttribute('target', '_blank');
document.body.appendChild(link);
link.click();
},
If I try to run this test as is - it starts, double-clicks span, then new tab opens, focus switches to it, I see correct page and test text on it, but test fails because it does not see requested text because it seems that though I see that tab changed the WebDriver remains on first tab.
I tried switchToNextTab() - it does not work. Sometimes switchToNextTab() 3 times in a row works, sometimes not.
I tried reloadPage() - it reloads first tab, not the one recently opened.
I tried
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles=$webdriver->window_handles();
$last_window = end($handles);
$webdriver->focusWindow($last_window);
});
and it seems that there is one currently active window in terms of this method ($handles is an array of 1 element).
I tried closeTab() - it closes entire Firefox instance.
How can I programmatically change active tab?

AngularJS $localstorage not working in other tab

I am trying to execute a fuction when a change occurs in one tab, the change should reflect in other tab too.
i write this and it is working fine in the same tab i change even i check manually browser localstorage and see it works nice.
but the problem, the change not reflect in other tab too.
I mean, i opened two tab and when i change something in one tab, in other tab it should reflect.
Whenever any change occurs in one tab, 2nd tab should execute this $scope.getAllContact(); and wait for another change, if another change occurs, $scope.getAllContact(); should be executed.
$localStorage.editedData = response.data;
$scope.editedID = $localStorage.editedData.id;
if (response.data.id == $localStorage.editedData.id) {
$localStorage.isChanged = true;
}
while ($localStorage.isChanged == true) {
$scope.getAllContact();
break
}
I write above code;
Ignore below this code if you undertand above few line, below code is fuction, when change occurs, the fuction should be executed:
$scope.getAllContact = function() {
var data = $http.get("http://127.0.0.1:8000/api/v1/contact")
.then(function(response) {
$scope.contacts = response.data;
// below two line of codes will reload in every 10 millisecond if a request succcess
// in result, you will see refleation in other browser if any change occurs in another browser
// do nothing for now
}, function(response) {
//$scope.connectionError = "Opps ! Having Trouble in loading this page ! \n It's Connection Error !!!";
// below two line as as above two commented line
// do nothing for nw
});
};
$scope.getAllContact();
You need to check your local storage at a certain time difference
setInterval(function(){
if ($localStorage.isChanged == true) {
$scope.getAllContact();
}
}
}, 500);
See below code may helpfull
$scope.$apply(function() {
$scope.contacts = response.data;
});
or
As per my assumption at a time you can see only one tab. So,call $scope.getAllContact()
whenever your clicking on second tab.

Protractor - Unable to access element due to fixed Top navigation bar

I'm facing the following issue in protractor with jasmine
Click/mouse hover not working because of fixed top navigation bar in my application. I need to click/perform mouse hover on a web page.
Unfortunately that element is displaying behind that fixed navigation bar. So scroll till element present & click by x & y coordinates are not working.
My dependencies are :
protractor version 5.2.2
node 8.9.3
selenium standalone 3.13
chrome driver-2.40
chromebrowser v67
OS- Windows 10
Thanks in advance
Try using prototype executeScript
Just try clicking that element from the browser console using id,name or xpath.
For example :
var el = element(by.module('header'));
var tag = browser.executeScript('return arguments[0].click()', el).then(function() {
expect(something).toMatch(something);
});
Another way, along the same lines as what Bharath Kumar S and knowing JeffC's caveat that this approach is cheating, I had a similar issue where the App-Header kept getting in my way of clicking, and I knew I was willing to never need it (so, for instance, to find other ways to navigate or log out and not check for stuff that was on it). I, therefore, did the following, which solved the problem. Note if you refresh the screen, you have to call it again. Also note I am using a number of functions from https://github.com/hetznercloud/protractor-test-helper, which do what you would expect from their names.
var removeAppHeaderIfAny = async function() {
//this function hides the app header
//it is useful to avoid having covers there when Protractor worries that something else will get the click
let found = false;
try {
found = await waitToBeDisplayed(by.className("app-header"), 2000);
} catch (e) {
let s: string = "" + e;
if (s.search("TimeoutError") != 0) flowLog("presumably fine, cover already removed: " + e);
found = false;
}
if (!found) return;
if (found) {
let coverElement = await element(by.className("app-header"));
browser.executeScript(
"arguments[0].style.visibility='hidden';",
coverElement
);
await waitToBeNotDisplayed(by.className("app-header"), 10000);
}
return;
//note after this is called you will not see the item, so you cannot click it
};
As I look at the code, it strikes me one can probably remove the if (found) and associated brackets at the end. But I pasted in something I know has been working, so I am not messing with that.
As indicated up front, I knew I was willing to forego use of the app-header, and it is a bit crude.

Why/how do the elements of this array change between the console.log calls?

I have an anuglarJS controller that calls an API via a service to return data. Ths issue is that sometimes, the data is not being updated in a directive that uses the data that is returned.
However, digging into this resulted in observing some very strange behavior. I added several console logs to debug what was happening, and discovered that the number of items in a property on the array is changing from one console call to the next.
The controller code is as follows:
init(){
this.ftService.getSitePromise(true).then((result: ng.IHttpPromiseCallbackArg<Site>) => {
let ctrl = this;
ctrl.isLoadingItems = true;
ctrl.hideSplash = true;
ctrl.siteReady = true;
ctrl.curSite = result.data;
ctrl.curSite.Items = [];
console.log("end of header site call");
ctrl.$timeout(function () {
console.log(ctrl.curSite.Items);
console.log("start get site items first call")
ctrl.ftService.getSitePromise(false).then((result: ng.IHttpPromiseCallbackArg<Site>) => {
console.log("return first call result.data.Items: " + result.data.Items.length);
ctrl.curSite.Items = result.data.Items;
ctrl.isLoadingItems = false;
console.log("return first call ctrl.curSite.Items: " + ctrl.curSite.Items.length);
console.log(ctrl);
console.log(ctrl.curSite);
console.log(ctrl.curSite.Items);
});
}, 200);
});
}
The console from this code executing, when the data isn't being shown as expected is as follows:
Any insight as to how this is occurring, and/or how I might correct it, would be greatly appreciated.
Edit: I didn't read the comments before posting. I didn't see your problem was solved. Hopefully this may help someone else in the future??
Why/how do the elements of this array change between the console.log calls?
Objects can change in console.log calls because the deeper nested properties are accessed lazily meaning that the console will only grab them when you click the little arrow to expand the object or if they are a shallow property.
You can change this behavior by cloning the object using Object.assign though you may need to clone the object deeply (which Object.assign({}, myObj) does not.
The stackoverflow snippet console won't show the correct results. Open your chrome dev tools to see the real result.
// OPEN THE DEVELOPER TOOLS CONSOLE
let myObj = {
shallowProp: 'some value',
arr: ['initial value']
};
// notice that when this logs, it seems like the change to myObj happens before the log but it does not
console.log(
'myObj initial log',
myObj
);
// using `Object.assign` clones the object so that when expanded in the console, the value is the initial value
console.log(
'myObj initial log with Object.assign',
Object.assign({}, myObj)
);
// when the value is actually changed
myObj.arr = ['new value'];
// the final state
console.log('myObj after change', myObj);
Conclusion: try cloning your object before logging it the console.

Ext.Msg.Confirm - wait for a user response?

I understand that Ext.Msg.Confirm is asynchronous, and will proceed if you do not provide a callback.
Below is my code - this is called if the user tries to navigate from the current screen while in edit mode. I'm passing in a callback to the method - fn is my callback event, but regardless of how I code this the logic continues to navigate away from the page. Is there anyway to stop propagation until the user has selected yes or no in the confirmation box?
Here is the code for the Confirmation:
displaySaveConfirmation: function(fn) {
var title = 'Do you want to Save?'
var msg = 'You are currently Editing Standard Text. Would you like to save your changes?'
var box = Ext.Msg.confirm(title, msg, function(buttonId, value) {
if (buttonId === 'no'){
fn.call();
} else {
return false;
}
}, this );
box.setZIndex(400);
box.setCls('alert-box');
var buttons = Ext.ComponentQuery.query('button', box);
for (var i=0; i<buttons.length; i++) {
if (buttons[i].getItemId()=="no")
buttons[i].addCls('blackBtn');
else if (buttons[i].getItemId()=="yes")
buttons[i].addCls('blueBtn');
this.addReleaseEvent(box, buttons[i]);
}
},
As of now you do the following:
The event is fired
You open the MessageBox
Your function returns, and it does not return "false".
The browser navigates away before the user can click "yes" or "no".
What you want to do is the following:
The event is fired
You open the MessageBox
Your function returns false.
The browser does not navigate away.
The user clicks "yes" or "no".
If the answer is "yes", you navigate to the previously requested target page manually (e.g. close the browser window, use history.back() or similar).
Alternatively, if the work to get that up and running (and tested, with all the possible cases how to navigate away and how to find the target) is too much, you can opt for the window.alert dialog instead, which does not look nearly as nice, but works synchronously.
Or you can do as I did: I just returned false after bringing up a MessageBox that says: "You cannot leave the page during edit. Please save or abort the post."

Resources