My selenium code is deployed in jenkinns which is in unix machine. When my schedulers trigger a job suite, job will run on selenium nodes which are in windows. Gere, i have a test case where file is downloaded in one of the node and i need to verify that downloaded file.
How can i identify a downloaded file in windows from unix machine
(Both are different environments).
If you are wish to verify this on chrome, following code is a solution.
Note: its written on typescript so you have to adapt it.
function checkChromeForDownloadedFile(fileName: string, state: string = 'COMPLETE') {
// open new tab
await browser.executeScript('return window.open()');
// switch to downloads tab window
let tabs: string[] = await browser.getAllWindowHandles();
await browser.switchTo().window(tabs[1]);
// open downloads page
await browser.get('chrome://downloads');
// 1 sec delay.
await browser.sleep(1000);
let downloadedItems;
try {
await browser.wait(() => {
// fetch downloaded items
return browser.executeScript('return downloads.Manager.get().items_').then((result) => {
downloadedItems = result;
if (!downloadedItems) {
return false;
}
// search for downloaded file with state complete and filename
return downloadedItems.some(i => i.file_name === fileName && i.state === state.toUpperCase());
}).catch( () => {
return false;
});
}, 10000, `File ${fileName} with download sate ${state} was not found within 10 seconds`);
} catch (error) {
console.log('there was an error while trying to fetch downloaded files');
throw error;
}
// close the tab
await browser.close();
// switch back to original window
await browser.switchTo().window(tabs[0]);
}
Related
I am writing a quick proof-of-concept for downloading images from Azure Blob Storage using the Java 12 Azure Storage SDK. The following code works properly when I convert it to synchronous. However, despite the subscribe() at the bottom of the code, I only see the subscription message. The success and error handlers are not firing. I would appreciate any suggestions or ideas.
Thank you for your time and help.
private fun azureReactorDownload() {
var startTime = 0L
var accountName = "abcd"
var key = "09sd0908sd08f0s&&6^%"
var endpoint = "https://${accountName}.blob.core.windows.net/$accountName
var containerName = "mycontainer"
var blobName = "animage.jpg"
// Get the Blob Service client, so we can use it to access blobs, containers, etc.
BlobServiceClientBuilder()
// Container URL
.endpoint(endpoint)
.credential(
SharedKeyCredential(
accountName,
key
)
)
.buildAsyncClient()
// Get the container client so we can work with our container and its blobs.
.getContainerAsyncClient(containerName)
// Get the block blob client so we can access individual blobs and include the path
// within the container as part of the filename.
.getBlockBlobAsyncClient(blobName)
// Initiate the download of the desired blob.
.download()
.map { response ->
// Drill down to the ByteBuffer.
response.value()
}
.doOnSubscribe {
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Subscription arrived.")
startTime = System.currentTimeMillis()
}
.doOnSuccess { data ->
data.map { byteBuffer ->
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> READY TO WRITE TO THE FILE")
byteBuffer.writeToFile("/tmp/azrxblobdownload.jpg")
val elapsedTime = System.currentTimeMillis() - startTime
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Finished downloading blob in $elapsedTime ms.")
}
}
.doOnError {
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Failed to download blob: ${it.localizedMessage}")
}
.subscribe()
}
fun ByteBuffer.writeToFile(path: String) {
val fc = FileOutputStream(path).channel
fc.write(this)
fc.close()
}
I see someone asking the same question 4 months ago and getting no answer:
Azure Blob Storage Java SDK: Why isn't asynchronous working?
I'm going to conjecture that this part of the JDK just isn't working right now. I wouldn't recommend using Azure's version of Java.
You should be able to accomplish it another way perhaps one of these answers:
Downloading Multiple Files Parallelly or Asynchronously in Java
I've worked with Microsoft and have a documented solution at the following link: https://github.com/Azure/azure-sdk-for-java/issues/5071. The person who worked with me provided very good background information, so it is more than just some working code.
I have opened a similar query with Microsoft for the downloadToFile() method in the Azure Java SDK v12, which is throwing an exception when saving to a file.
Here is the working code from that posting:
private fun azureReactorDownloadMS() {
var startTime = 0L
val chunkCounter = AtomicInteger(0)
// Get the Blob Service client, so we can use it to access blobs, containers, etc.
val aa = BlobServiceClientBuilder()
// Container URL
.endpoint(kEndpoint)
.credential(
SharedKeyCredential(
kAccountName,
kAccountKey
)
)
.buildAsyncClient()
// Get the container client so we can work with our container and its blobs.
.getContainerAsyncClient(kContainerName)
// Get the block blob client so we can access individual blobs and include the path
// within the container as part of the filename.
.getBlockBlobAsyncClient(kBlobName)
.download()
// Response<Flux<ByteBuffer>> to Flux<ByteBuffer>
.flatMapMany { response ->
response.value()
}
.doOnSubscribe {
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Subscription arrived.")
startTime = System.currentTimeMillis()
}
.doOnNext { byteBuffer ->
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CHUNK ${chunkCounter.incrementAndGet()} FROM BLOB ARRIVED...")
}
.doOnComplete {
val elapsedTime = System.currentTimeMillis() - startTime
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Finished downloading ${chunkCounter.incrementAndGet()} chunks of data for the blob in $elapsedTime ms.")
}
.doOnError {
println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Failed to download blob: ${it.localizedMessage}")
}
.blockLast()
}
I am testing around with PhantomJS a bit.
But I am not sure how to make it work with a java application, th examples I have found are mostly just against files or sites.
So this is what I have now.
var page = require('webpage').create();
address = "http://localhost:8080/logon.do";
page.open(address, function(status) {
wait(5000);
if (status !== 'success') {
console.log('Unable to access network');
} else {
var ua = page.evaluate(function () {
return document.getElementsByTagName('html')[0].outerHTML;
});
console.log(ua);
}
phantom.exit();
});
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
Now I know this wait is ugly but it is not important right now.
The server is running and if I go to the url I get a log in page.
I was expecting this log in page to be the output of console.log(ua);
Instead I get the output:
<-html><-head><-/head><-body><-/body><-/html>
What am I missing?
OK this turned out to be very secific for our application so lets close this.
Sascha, yes it is the script called by phantomjs which in turn
Hello I want to learn how to switch in in to a new windows without using thread sleep. I was trying to use awaitility artifact but I was not able to done it correctly. I was trying to automate print window. When I click on print icons on my web page I navigate to print window I want to wait while navigating to print window and once print window displayed I want to click on cancel button. Can someone help me for that
Print_icon.click();
await().atMost(10,TimeUnit.SECOND).pollInterval(1,TimeUnit.SECONDS);
Cancel_button.click();
You can try this :
Print_icon.click();
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
}
boolean elmnt = false;
boolean timeOut = false;
int second = 1;
do {
try {
if(second>30) {
timeOut = true;
}
Cancel_button.click();
elmnt=true;
} catch (Exception e) {
TimeUnit.SECONDS.sleep(1);
second++;
}
}while(elmnt==false && timeOut==false);
You can't handle windows dialogs so I suggest you review your page code and find the name of the method that opens the print window and override it. In your test case for example you can override print method to do nothing, like this:
((JavascriptExecutor)driver).executeScript("window.print=function(){};");
I've often faced an issue, how to download files in IE.
In contrast to Chrome of Firefox, you cannot just specify required folder, and all the files will be downloaded to that folder. You also need to interact with native Windows forms and so on.
There are multiple options, like using AutoIt, using keyboard commands, Robot and etc... But all this options aren't stable, they require explicit waiting, using redundant libraries, and non-appropriate when run tests in parallel. The other problem, is what to do, if the file isn't downloaded by direct link, but link is generated from javascript command or received from server, and cannot be extracted from html.
All these problems can be solved, here in hte answer i'll show how to do it.
Solution is written in c#, i believe the same can be implemented in java
Method DownloadFileIexplore will download file to the specified filePath (folder + filename), e.g. DownloadFileExplore("C:\my_folder\report.xslx")
public void DownloadFileIexplore(string filePath)
{
//Click the link.
//Simple click can be used instead, but in my case it didn't work for all the links, so i've replaced it with click via action:
new Actions(Browser.Driver).MoveToElement(Element).Click(Element).Perform();
//Different types of element can be used to download file.
//If the element contains direct link, it can be extracter from 'href' attribute.
//If the element doesn't contains href or it's just an javascript command, link will be extracted from the browser http requests.
//
string downloadUrlOrLink = Element.GetAttribute("href") != null && !Element.GetAttribute("href").Contains("javascript")
? Element.GetAttribute("href")
: GetRequestUrls().Last() ?? GetLinkInNewWindowIexplore();
if (downloadUrlOrLink == null)
{
throw Log.Exception("Download url cannot be read from the element href attribute and from the recent http requests.");
}
/// the last step is to download file using CookieWebClient
/// method DownloadFile is available in the System.Net.WebClient,
/// but we have to create new class CookieWebClient, that will be inherited from System.Net.WebClient with one overriden method
new CookieWebClient(GetCookies()).DownloadFile(downloadUrlOrLink, filePath);
}
/// <summary>
/// this method returns all the http requests sent from browser.
/// the latest requests was send when link (or button) was clicked to download file
/// so we will need just to get last element from list: GetRequestUrls().Last().
/// or, if the request for file downloading isn't the last, find the required request by part of url, in my case it was 'common/handler', e.g.:
/// GetRequestUrls().LastOrDefault(x => x.Contains("common/handler"))
/// <summary>
public List<string> GetRequestUrls()
{
ReadOnlyCollection<object> requestsUrls = (ReadOnlyCollection<object>)
Driver.ExecuteScript("return window.performance.getEntries().map(function(x) { return x.name });");
return requestsUrls.Select(x => (string) x).ToList();
}
/// <summary>
/// In some cases after clicking the Download button new window is opened in IE.
/// Driver.WindowHandles can return only one window instead of two.
/// To solve this problem reset IE security settings and set Enable Protected Mode for each zone.
/// </summary>
private string GetLinkInNewWindowIexplore()
{
/// here it would be better to add waiting till new window is opened.
/// in that case we have to calculate number of windows before click and send this number as argument to GetLinkInNewWindowIexplore()
/// and wait till number will be increased by 1
var availableWindows = Driver.WindowHandles;
if (availableWindows.Count > 1)
{
Driver.SwitchTo().Window(availableWindows[availableWindows.Count - 1]);
}
string url;
try
{
url = Driver.Url;
}
catch (Exception)
{
url = Driver.ExecuteScript("return document.URL;").ToString();
}
Driver.SwitchTo().Window(Driver.WindowHandles[0]);
return url;
}
public System.Net.CookieContainer GetCookies()
{
CookieContainer cookieContainer = new CookieContainer();
foreach (OpenQA.Selenium.Cookie cookie in Driver.Manage().Cookies.AllCookies)
{
cookieContainer.Add(new System.Net.Cookie
{
Name = cookie.Name,
Value = cookie.Value,
Domain = "domain of your site, you can find, track http requests send from your site in browser dev tools, tab Network"
});
}
return cookieContainer;
}
public class CookieWebClient : WebClient
{
private readonly CookieContainer _cookieContainer;
public CookieWebClient(CookieContainer cookieContainer)
{
_cookieContainer = cookieContainer;
}
/// it's necessary to override method to add cookies, because file cannot be download by non-authorized user
/// ServerCertificateValidationCallback is set to true to avoid some possible certificate errors
protected override WebRequest GetWebRequest(Uri address)
{
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = _cookieContainer;
}
return request;
}
}
I have created an automation program using java selenium.I have used TestNG framework.
I want to record (video) of the screen those are getting executed during the script execution so it is better to track the failed/passed scenario and view the execution process.
Can any one help me with this, how to record the screen during running the automation suite execution.
Problems with solution mentioned before :-
All solutions answered to record video, records test execution from start to end. If automation suite run for hours then this won't be practical and optimal solution.
Main purpose of record video is to SEE what exactly happened when automation test case failed. So precisely testers need video recording of LAST 15 SECONDS BEFORE TEST CASE FAILED. They don't need any recording for PASSED test cases
Solution in theory :-
On Windows 10 onwards, Windows Xbox Game bar [Windows+G] has ability to capture LAST 15 seconds [customizable] of video. Keyboard shortcut Windows+Alt+G is use to capture last 15 seconds of video using XBox Game Bar and it would be stored in folder mentioned in settings.
Selenium automation can exploit this recording feature of Windows Xbox Game bar.
In your testNG automation project, in onTestFailure method of testNG listener just add code to keypress Windows+Alt+G to capture last 15 seconds video. This would capture video for ONLY failed test cases and never for PASS test cases. If you are using Java then you can use Robot library to send keypress programatically.
Screenshots showing Windows XBox game Bar and it's setting to capture last 15 seconds.
Solution in Code :-
I am calling below recordFailedTCVideo() method from testNG listner's
public void onTestFailure(ITestResult result) method.
This will just record last 15 seconds of video ONLY for failed test cases.[and not for PASS test cases]
Video explanation :- https://www.youtube.com/watch?v=p6tJ1fVaRxw
public void recordFailedTCVideo(ITestResult result) {
//private void pressKey() {
System.out.println("In recordFailedTCVideo::***In Try Block *** Video for test case failed " + result.getName());
commonUtility.logger.error("BaseTest::recordFailedTCVideo::***In Try Block *** Video for test case failed " + result.getName());
try {
// Useing Robot class to keypres Win+Alt+G which will capture last 15 seconds of video
Robot r = new Robot();
r.keyPress(KeyEvent.VK_WINDOWS );
Thread.sleep(1000);
r.keyPress(KeyEvent.VK_ALT );
Thread.sleep(1000);
r.keyPress(KeyEvent.VK_G );
Thread.sleep(5000);
r.keyRelease(KeyEvent.VK_WINDOWS);
Thread.sleep(1000);
r.keyRelease(KeyEvent.VK_ALT);
Thread.sleep(1000);
r.keyRelease(KeyEvent.VK_G);
Thread.sleep(5000);
/// Copy Video saved to desired location
File srcDir = new File(commonUtility.prop.getProperty("VIDEO_CAPTURE_DEFAULT_LOCATION"));
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd HHmmss");
LocalDateTime now = LocalDateTime.now();
String destination = ".\\ScreenshotsAndVideos\\" + dtf.format(now) ;
File destDir = new File(destination);
try {
System.out.println("In RecordFailedTCVideo::Source Folder is "+ srcDir +" Destination Folder = " + destDir);
commonUtility.logger.error("In RecordFailedTCVideo::Source Folder is "+ srcDir +" Destination Folder = " + destDir);
FileUtils.moveDirectory(srcDir, destDir);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("In recordFailedTCVideo::***In Catch Block ***\n" +e);
commonUtility.logger.error("BaseTest::recordFailedTCVideo::***In Catch Block *** \n"+e );
e.printStackTrace();
}
//}
}
Further Video explanation :-
https://www.youtube.com/watch?v=p6tJ1fVaRxw
Constraints :-
This solution is not for non-Windows platforms.
XBar Game utility would not record Windows Explorer , text files etc. Although it records browsers without problem.
See this API (Monte Library): http://www.seleniummonster.com/boost-up-your-selenium-tests-with-video-recording-capability/
and this link: http://unmesh.me/2012/01/13/recording-screencast-of-selenium-tests-in-java/
Example Code (from above links):
public void startRecording() throws Exception
{
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
this.screenRecorder = new ScreenRecorder(gc,
new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI),
new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
CompressorNameKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,DepthKey, 24, FrameRateKey, Rational.valueOf(15),QualityKey, 1.0f,KeyFrameIntervalKey, 15 * 60),new Format(MediaTypeKey,MediaType.VIDEO, EncodingKey, "black",FrameRateKey, Rational.valueOf(30)),null);
this.screenRecorder.start();
}
public void stopRecording() throws Exception
{
this.screenRecorder.stop();
}