Delay after downloading a file in Protractor test - file

My test downloads a file and then clicks a button. The click on the button takes effect (opening a sidebar) 40 secs after. If I disable the downloading code in the app (making the bottom download bar not to appear), the sidebar opens right away without delay.
My question is roughly the same as this one. The question has no solution and is quite old, that's why I ask again.
What I have tried:
reduce timeout with browser.manage().timeouts().implicitlyWait(100);
browser.ignoreSynchronization = true; before downloading (and browser.ignoreSynchronization = false; after)
await browser.waitForAngularEnabled(false); before downloading (and await browser.waitForAngularEnabled(true); after)
browser.executeScript('window.stop();'); after downloading
const wins = await browser.driver.getAllWindowHandles(); await browser.switchTo().window(wins[0]); after downloading
await browser.switchTo().activeElement(); after downloading
const bd = element(by.css("body")); await browser.actions().mouseMove(bd, { x: 0, y: 0 }).click().perform(); after downloading
browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); after downloading
let ChromeDriver use a Chrome extension to disable bottom download bar (such as this one)
I don't know what is happening, that's why I tried various (and maybe unrelated with the cause) things.
Thank you.

After searching and trying various things, solved with
browser.controlFlow().execute(function () {
browser.ignoreSynchronization = false;
});
before downloading and
browser.controlFlow().execute(function () {
browser.ignoreSynchronization = true;
});
after.
Can anybody explain me why ?

Related

Taskpane Word Add-Ins (office-js) - The Search function return empty object {} in Word 365 online

I have created a Taskpane Word Add-Ins, written in React Typescript.
This sideload add-in is going to search a list of words in Word document and replace them by new words. All functionality works well in desktop MS Word and find all the words. When I upload manifest to Word 365 online, Taskpane loads and looks find but when I click on button to search, then nothing find. The result of search function is always empty object {}
Below you can see my code for searching part that will trigger when user click on search button. It is working on desktop version but is not working in Word 365 online
(async () => {
try {
let options = Word.SearchOptions.newObject(context);
options.matchCase = false;
options.matchWholeWord = true;
options.ignorePunct = true;
await Promise.all(
WordList.map(async (data: customWord) => {
// NOTE: In Word 365 online, searchResults is always {}
const searchResults = textSelected
? context.document.getSelection().search(data.word, options)
: context.document.body.search(data.word, options);
searchResults.load("items, text");
allSearchResults.push(searchResults);
})
);
} catch (error) {
console.error(error);
}
})();
Does anyone know why search result is empty in Word Online? Is it related to code Promise.all() when running via browser?
I figured it out where the issue comes from. This issue occurs when having matchWholeWord option in your search function or al least set it to True. By removing this option I was able to see the result in Word online eventhough the result I got wasn't as I expected which is make sense. I didn't try for other search options and don't know for others and these are only three of in my case. Below is my change to get result in Word online.
let options = Word.SearchOptions.newObject(context);
options.matchCase = false;
options.ignorePunct = true;
This is a SearchOption bug in Word online which is reported as an issue in office-js GitHub repo.
https://github.com/OfficeDev/office-js/issues/218
Microsoft common! Fix it! We need it!

Tampermonkey run script on specific tab

I'm on learning Tempermonkey and it's userscripts. And I have some questions.
I want to run one script for all firefox opened containers but this script must have different settings according the container's tab it ran on. Like some data and different conditions in some functions.
I tried to use GM_getTab for that but it sends me an empty object for some reasons.
// #grant GM_getTab
GM_getTab(function (e) {
console.log(e); // 'e is empty in console and in debug window either'
});
So basically how to use this function for my task?
P.S. Firefox: Portable 93.0 (64-bit)
Omg why always like this, just asked the question and found the solution in next 10 minutes :D
So the solution is:
(async () => {
const tabObj = await GM.getTab();
// You first have to define ID for all tabs you need, then just comment this part
tabObj.id = Math.random();
GM_saveTab(tabObj); // update the object
// get all stored objects
const tabsDatabase = await GM.getTabs();
const dbL = Object.keys(tabsDatabase).length;
console.log('Script-owned tab:', tabObj); // Current tab
console.log('Script-owned tabs count:', tabsDatabase); // All opened tabs
})();

custom PWA version management

Is is possible to get the onload event for the pwa application in general. I meant we had implemented the a custom versioning logic in-order to keep the app version based on database field.(ie clearing the service worker cache). The issues here is the logic almost works but when ever a new version is updated in the database, then we need to clear the cache of the respective browser in-order to trigger the update. On more investigation I found that when once the pwa app is opened, it is keeping the some sort of cache image, on reopening the pwa app again won't trigger the start-up code of the app, but load app from cache.
So is it possible to get an onload sort of event for pwa ?
For testing purpose I added some alert() in the app component, but didn't fired, on reopening a pwa app
this.httpService.GetAppVersion(ver).subscribe(
res => {
if (res != null || res !== undefined) {
this.version = res.versionNumber;
ver = localStorage.getItem("appVersion");
if (ver === null || ver === undefined) {
localStorage.setItem("appVersion", "1.0");
ver = "1.0";
}
let localVersion = ver.split(".");
let incomingVersion = this.version.split(".");
let result = this.helperService.compareVersion(
localVersion,
incomingVersion
);
//alert("result : " + result);
if (result === 1) {
const snackBarRef = this.snackBar.open(
"New version available. Load New Version?",
"Yes",
{ duration: 50000000 }
);
snackBarRef.afterDismissed().subscribe(() => {
console.log("The snack-bar was dismissed");
});
snackBarRef.onAction().subscribe(() => {
localStorage.setItem("appVersion", this.version.toString());
this.helperService.Update(); // which clears the cache
setTimeout(() => {
window.location.reload(true);
}, 500);
});
}
}
},
error => {
alert("http error" + JSON.stringify(error));
}
);
at least the code in the app component's constructor will execute every time when the app is reopened after closing.
See: How to display a "new version available" for a Progressive Web App
I know this question is very old, but what I'm doing now (and I'm trying to find a better approach because I don't really like this one) is storing the version on the service worker code.
Then, when the window.onload fires, the main JavaScript code sends a message to the service worker (using postMessage()) and the service worker replies with the version number.
It's not exactly what you need, but it's an approximation.
Still, and as I said, I'm looking for a better, more maintenable approach. If I find one I'll post it here, just in case someone is searching for this (as I did).

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.

Can protractor be made to run slowly?

Is there a way to run a Angular E2E test written using protractor slowly so that I can watch what is happening?
Below is my solution to do that. So basically I created a decorator for current control flow execute function, which now additionaly queues a delay of 100ms before each queued action.
This needs to be run before any tests are invoked (outside describe block)
var origFn = browser.driver.controlFlow().execute;
browser.driver.controlFlow().execute = function() {
var args = arguments;
// queue 100ms wait
origFn.call(browser.driver.controlFlow(), function() {
return protractor.promise.delayed(100);
});
return origFn.apply(browser.driver.controlFlow(), args);
};
Just like George Stocker said in the comment, I don't know why you would want to do this...but you can always add a sleep wherever you want in your test.
browser.sleep(6000);
Previous answers look more like workaround. Another way is to add param to Protractor config:
highlightDelay: 1000
And change to:
directConnect: false
It will delay Protractor actions like clicking or typing for 1 second and will highlight in light blue.
You can enter in 'debug mode' by placing in your code the command:
browser.pause();
In the debug mode, you would see the following output in your terminal:
------- WebDriver Debugger -------
ready
press c to continue to the next webdriver command
press d to continue to the next debugger statement
type "repl" to enter interactive mode
type "exit" to break out of interactive mode
press ^C to exit
You could then:
Run command by command by entering c
Continue to the next debugger statement (next browser.pause()) by entering d
Enter in interactive mode where you could interact with all the elements by entering repl
2 ways for doing this
1. First is very childish way, but I'll leave it here
you can highlight the elements you're interacting with!
highlightElement: async ($elementObject, time = 1000) => {
async function setStyle(element, style) {
const previous = await element.getAttribute('style');
await element.setAttribute('style', style);
await setTimeout(() => {
element.setAttribute('style', previous);
}, time);
}
await browser.sleep(time)
return await browser.executeScript(await setStyle, $elementObject.getWebElement(), 'color: red; background-color: yellow; z-index: 9999;');
},
This will highlight the element for a second
And then wrap your actions using this element
let click = async function ($elem) {
await highlightElement($elem);
await $elem.click();
}
let sendKeys = async function ($elem, text) {
await highlightElement($elem);
await $elem.sendKeys(text);
}
And then use it to try some scripts
await sendKeys($login, username);
await sendKeys($password, password);
await click($submit);
This shouldn't really be used in the real script, only when you're playing with it
2. Setup debugging configuration in your code editor
Example for vs code https://medium.com/#ganeshsirsi/how-to-debug-protractor-tests-in-visual-studio-code-e945fc971a74, but the same thing can be achieved in webstorm
This will allow you to execute the code line by line and interact with the variables in the real time. MUST HAVE for everyone who works with protractor. I'm serious

Resources