Protractor File Upload to a Link - selenium

I'm trying to upload a file using protractor and typescript. The upload button is on a toolbar that holds two other buttons as well. Unlike many of the examples I saw here, this upload button is implemented as a link and not an input.There is this warning in the console. There is no error, but the file isn't getting uploaded.
Warning below:
more than one element found for locator By(css selector, a.mat-icon-button) - the first result will be used
HTML below :
This is how I am trying to upload the file.
const fileToUpload = './Test_file.xlsx';
const absolutePath = path.resolve(__dirname, fileToUpload);
const uploadlink = element(by.css('a.mat-icon-button'));
uploadlink .sendKeys(absolutePath);

In that situation, if you are working in the Windows environment, I recommend looking into AutoIT.
It's very simple to script and use.
https://www.autoitscript.com/site/

more than one element found for locator By(css selector,
a.mat-icon-button) - the first result will be used
If you have 3 elements, and 3rd one is the element that handles upload, other 2 are just a link ref ?
Try to write more specific locator to the "upload" a tag.
can you verify on clicking of the button, if an input is present inside the code?
If there is no other solution use AutoIt.

const fileToUpload = './Test_file.xlsx';
const absolutePath = path.resolve(__dirname, fileToUpload);
const uploadlink = element(by.css('a.mat-icon-button>span.mat-button-wrapper>div.command-text'));
uploadlink .sendKeys(absolutePath);
If the above doesn't help try javascript executer
https://blog.ng-book.com/executing-raw-javascript-in-protractor/

Related

How can I provide a tag that would run my cucumber background once for all scenarios?

I am using cucumber-js
I have some slides within the same url. For my feature, I want to provide the tester a way to open a url, and then have multiple scenarios on the same url:
The problem with the solution below is that the url re-opens for every scenario, reseting the slide to the start. I can never test each slide step as a separate scenario.
Any help or suggestion appreciated: example:
Feature: Valuation slide user journey - pre-reqisite As a developer I want to open the url /valuation/
Background:
Given I open the url "/valuation/"
Scenario: Test valuation slide button
Given the element "valuationIntro" is visible
When I click on the button "valuationIntro.cta"
Then I expect that element "valuationSlide1" becomes visible
Scenario: Test valuation autocomplete
Given the element "valuationSlide1.cta" has the class "invalid"
When I set "jk5 7kj" to the inputfield "valuationSlide1.autocomplete"
Then I expect that element "valuationSlide1.cta" does not have the class "invalid"
I understand I can use tags, but not entirely sure how I can use a tag to run a background once.
var executed = false;
var myStepDefinitionsWrapper = function () {
this.Given(/^I open the url "([^"]*)"$/, function (url) {
if (!executed)
// do some work with url
executed = true;
});
};
module.exports = myStepDefinitionsWrapper;
Just a simplification to make a point. I would use singletons with state.

Handle download dialog box in SlimerJS

I have written a script that clicks on a link which can download a mp3 file. The problem I am facing is when the script simulates the click on that link, a download dialog box pops up like this:
Download Dialog Box
Now, I want to save this file to some path of my choice and automate this whole process. I am clueless on how to handle this dialog box.
Here's a script adapted from this blog post to download a file.
In SlimerJS it is possible to use response.body inside the onResourceReceived handler. However to prevent using too much memory it does not get anything by default. You have to first set page.captureContent to say what you want. You assign an array of regexes to page.captureContent to say which files to receive. The regex is applied to the mime-type. In the example code below I use /.*/ to mean "get everything". Using [/^image/.+$/] should just get images, etc.
var fs=require('fs');
var page = require('webpage').create();
fs.makeTree('contents');
page.captureContent = [ /.*/ ];
page.onResourceReceived = function(response) {
if(response.stage!="end" || !response.bodySize)
{
return;
}
var matches = response.url.match(/[/]([^/]+)$/);
var fname = "contents/"+matches[1];
console.log("Saving "+response.bodySize+" bytes to "+fname);
fs.write(fname,response.body);
phantom.exit();
};
page.onResourceRequested = function(requestData, networkRequest) {
//console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
};
page.open("http://....mp3", function(){
});
You can't control a dialog box. SlimerJS doesn't have API for this action.
Firefox generates a temp "downloadfile.extension.part" file which contains the content. Just simply rename the file ex. myfile.csv.part > myfile.csv
locally if working on a mac you should find the .part file in the downloads directory, on linux /temp/ folder
Not the most elegant solution but should do the trick

How to use Google Translate TTS with the new V2 API?

I used to call Google Translate TTS to download an audio file using this url:
http://translate.google.com/translate_tts?tl=en&q=Hello+world!
However Google changed the way that works and therefore I can no longer download the audio files.
I've signed up for a free trial for Google Translate API V2, but can't find how to get the TTS audio files.
Any idea?
You can use that link without captcha..
https://translate.google.com/translate_tts?ie=UTF-8&tl=tr-TR&client=tw-ob&q=Batsın+bu+dünya+bitsin+bu+rüya
I stumbled across this thread and wanted to give my take on it, with reference to #Alexandre Andrade, mainly because he didn't submit any code.
I did this in a react app, but the same procedure should works for a vanilla web project.
I did add the meta tag to my head public/index.html,
<head>
...
<meta name="referrer" content="no-referrer">
...
</head>
Then added the audio tag in my component:
Javascript:
const playTTS = (text, lang) => {
// Get the audio element
const audioEl = document.getElementById('tts-audio');
const url= `https://translate.google.com/translate_tts?ie=UTF-8&tl=${lang}&client=tw-ob&q=${text}`;
// add the sound to the audio element
audioEl.src = url;
//For auto playing the sound
audioEl.play();
};
html
...
<audio controls id="tts-audio"/>
...
Then it's just a matter of hooking the function up to some of your life cycle methods. Since I wrote my react code in react hooks, I added the function call in one of my hooks to get it initialized when the component was loaded. (this would be in the componentDidMount() function otherwise).
Hope this helps anyone out!
try this link for English:
https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=en&q=Hello+World
For Chinese (Puthonghua)
https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=zh-CN&q=世界+你好
Text-to-speech was always an 'unofficial' API which is now captcha-protected to prevent abuse. It was never advertised as part of the Translate API, and currently there is no TTS functionality in the Translate V2 API, paid or otherwise.
There is some more background on the following groups thread which had been ongoing for some time.
Here's to those who have desperately been trying to play Google TTS as an audio in HTML: let me save you a couple of hours of time and tell you how to do it.
Let's say we have this link:
https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=en&q=I+love+coffee
If you try to play this audio given the link and using <audio>, <iframe>, using third-party libraries or playing it with Javascript...
var audio = new Audio('https://translate.google.com/translate_tts...');
audio.play();
...then you'll soon find out that none of the aforementioned ways work as Error 404 is being thrown.
Solution
Apparently, the only possible way to play this TTS generic audio is to utilise <embed> tag wrapped into a custom <iframe> and giving the link a unique version number (it is important, as caching by browsers prevents the audio from playing for some reason).
Here is the solution for our example: (assuming you have an iframe#ttsiframe)
function playTTS(lang,sentence) {
//get the iframe
var iFrame = document.getElementById('ttsiframe');
//remove its sandbox property
iFrame.removeAttribute('sandbox');
//this is your reference variable for the iframe body and head tag
var iFrameBody;
//get the body
if (iFrame.contentDocument) { // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
iFrameHead = iFrame.contentDocument.getElementsByTagName('head')[0];
}
else if (iFrame.contentWindow) { // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
iFrameHead = iFrame.contentWindow.document.getElementsByTagName('head')[0];
}
else {
iFrameBody = iFrame.contentDocument.body;
iFrameHead = iFrame.contentDocument.head;
}
//generate link to Google Translate TTS using arguments (pay attention to random version number at the end)
var link = 'https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=' + lang + '&q=' + sentence.replace(/ /g,'+').replace(/[.]/g,'') + '&rd=' + getRandomInt(0,50000000);
//add embed element with our link
iFrameBody.innerHTML = '<embed src="' + link + '" id="TTS">';
//isolate iframe
iFrame.setAttribute('sandbox','');
}
you can simply use the link:
Text to Speech

Switching to a window with no name

Using the Codeception testing framework and Selenium 2 module to test a website, I end up following a hyperlink that opens a new window with no name. As a result the switchToWindow() function will not work because it is trying to switch to the parent window (which I'm currently on). Without being able to switch to the new window I cannot perform any testing on it.
<a class="external" target="_blank" href="http://mylocalurl/the/page/im/opening">
View Live
</a>
Using both Chrome and Firefox debugging tools I can confirm the new window doesn't have a name, and I cannot give it one because I cannot edit the HTML page I am working on. Ideally I would have changed the HTML to use javascript onclick="window.open('http://mylocalurl/the/page/im/opening', 'myPopupWindow') however this is not possible in my case.
I've looked around on the Selenium forums without any clear method to tackle this problem, and Codeception doesn't appear to have much functionality around this.
After searching around on the Selenium forum and some helpful prods from #Mark Rowlands, I got it to work using raw Selenium.
// before codeception v2.1.1, just typehint on \Webdriver
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles=$webdriver->window_handles();
$last_window = end($handles);
$webdriver->focusWindow($last_window);
});
Returning back to the parent window was easy because I could just use Codeception's switchToWindow method:
$I->switchToWindow();
Building on the accepted answer, in Codeception 2.2.9 I was able to add this code to the Acceptance Helper and it seems to work.
/**
* #throws \Codeception\Exception\ModuleException
*/
public function switchToNewWindow()
{
$webdriver = $this->getModule('WebDriver')->webDriver;
$handles = $webdriver->getWindowHandles();
$lastWindow = end($handles);
$webdriver->switchTo()->window($lastWindow);
}
Then in the test class I can do this:
$I->click('#somelink');
$I->switchToNewWindow();
// Some assertions...
$I->switchToWindow(); // this switches back to the previous window
I had a heck of a time trying to figure out how to do this by just searching google, so I hope it helps someone else.
Try this,
String parentWindowHandle = browser.getWindowHandle(); // save the current window handle.
WebDriver popup = null;
Iterator<String> windowIterator = browser.getWindowHandles();
while(windowIterator.hasNext()) {
String windowHandle = windowIterator.next();
popup = browser.switchTo().window(windowHandle);
}
make sure to return on parent window using,
browser.close(); // close the popup.
browser.switchTo().window(parentWindowHandle); // Switch back to parent window.
I hope will help you.
Using Codeception 2.2+ it looks like this:
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles = $webdriver->getWindowHandles();
$lastWindow = end($handles);
$webdriver->switchTo()->window($lastWindow);
});

Selenium 2: How to save a HTML page including all referenced resources (css, js, images...)?

In Selenium 2, the WebDriver object only offers a method getPageSource() which saves the raw HTML page without any CSS, JS, images etc.
Is there a way to also save all referenced resources in the HTML page (similar to HtmlUnit's HtmlPage.save())?
I know I'm royally late with my answer, but I didn't really find an answer for this question when I was searching myself. So I did something myself, hope I can help some people still.
For c# here's how I did it:
using system.net;
string DataDirectory = "C:\\Temp\\AutoTest\\Data\\";
string PageSourceHTML = Driver.PageSource;
string[] StringSeparators = new string[] { "<" };
string[] Result = PageSourceHTML.Split(StringSeparators, StringSplitOptions.None);
string CSSFile;
string FileName = "filename.html";
System.IO.File.WriteAllText(DataDirectory + FileName, PageSourceHTML);
foreach(string S in Result)
{
if(S.Contains("stylesheet"))
{
CSSFile = S.Substring(28); // strip off "link rel="stylesheet" href="
CSSFile = CSSFile.Substring(0,CSSFile.Length-10); // strip off characters behind, like " />" and newline, spaces until next "<" was found. Can and probably will be different in your case.
System.IO.Directory.CreateDirectory(DataDirectory + "\\" + CSSFile.Substring(0, CSSFile.LastIndexOf("/"))); //create the CSS direcotry structure
var Client = new WebClient();
Client.DownloadFile(Browser.Browser.WebUrl + "/" + CSSFile, DataDirectory + "\\" + CSSFile); // download the file and save it with the same filename under the same relative path.
}
}
I'm sure it could be improved to include any unforeseen situations, but for my website in test it will always work like this.
Nope. If you can, go for HtmlUnit for this particular task.
The best you could do, I think, is Robot. Press Ctrl + S simultaneously, the confirm with Enter. It's blind, it's imperfect, but it's the closest thing to your need.
You can use the selenium interactions to handle it.
using OpenQA.Selenium.Interactions;
There are a few ways to do it as well. One of the ways that I handle something like this, is to find an item central to the page, or whichever area that you wish to save, and do an actions builder.
var htmlElement = driver.FindElement(By.XPath("//your path"));
Actions action = new Actions(driver);
try
{
action.MoveToElement(htmlElement).ContextClick(htmlElement).SendKeys("p").Build().Perform();
}
catch(WebDriverException){}
This will simply right click on the area, and then send the key "p" which is the 'Save Page As' hotkey in firefox when right clicking. Another way is to have the builder send the keys.
var htmlElement = driver.FindElement(By.Xpath("//your path"));
action.MoveToElement(htmlElement);
try
{
action.KeyDown(Keys.Control).SendKeys("S").KeyUp(Keys.Control).Build().Perform();
}
catch(WebDriverException){}
Note that in both cases, if you leave the scope of the driver, say a windows form, then you will have to switch your case / code to handle the windows form when it pops up. Selenium will also have issues with nothing being returned after the keys are sent, so the Try Catches are there for that. If anyone has a way to work around that, it would be awesome.