Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="JobFailureEventArgs" /> class.
 /// </summary>
 /// <param name="jobUrl">The job URL.</param>
 /// <param name="jobInfo">The job information.</param>
 /// <param name="browsers">The browsers.</param>
 /// <param name="exception">The exception that caused the failure.</param>
 public JobFailureEventArgs(string jobUrl, Job.JobInfo jobInfo, IEnumerable <Browser> browsers, Exception exception)
 {
     this.Exception = exception;
     this.Browsers  = browsers;
     this.JobInfo   = jobInfo;
     this.JobUrl    = jobUrl;
 }
Example #2
0
        /// <summary>
        /// The save screenshot async.
        /// </summary>
        /// <param name="screenshot">The screenshot.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="jobInfo">The job info.</param>
        /// <param name="rootPath">The root path.</param>
        /// <returns>
        /// The <see cref="Task" />.
        /// </returns>
        private async Task SaveScreenshotAsync(Screenshot screenshot, string jobId, Job.JobInfo jobInfo, string rootPath)
        {
            // Create the folder for the screenshot
            var directory = this.CreateScreenshotDirectory(jobInfo, screenshot.Browser, rootPath);
            var filename  = this.jobsToJobsToRun[jobId.ToLower()].Filename;

            try
            {
                if (screenshot.State == Screenshot.States.Done)
                {
                    var tasksToWaitFor = new List <Task>();
                    tasksToWaitFor.Add(this.screenshotsApi.SaveScreenshotToFileAsync(screenshot, directory.FullName, filename, false));

                    if (this.captureThumbnails)
                    {
                        tasksToWaitFor.Add(this.screenshotsApi.SaveThumbnailToFileAsync(screenshot, directory.FullName, filename + "_thumbnail", false));
                    }

                    await Task.WhenAll(tasksToWaitFor.ToArray());
                }
            }
            catch (Exception ex)
            {
                this.OnScreenshotFailed(new ScreenshotFailedEventArgs(screenshot, ex, filename));
            }

            this.ScreenhotsCompleted.Add(screenshot);
            this.OnScreenshotCompleted(new ScreenshotEventArgs(screenshot));
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BatchCaptureJobInfo"/> class.
        /// </summary>
        /// <param name="url">
        /// The URL to capture.
        /// </param>
        /// <param name="filenameTemplate">
        /// The filename template that will be used to capture the screenshot.
        /// </param>
        /// <param name="jobInfo">
        /// The job information.
        /// </param>
        /// <param name="browsers">
        /// The browsers.
        /// </param>
        public BatchCaptureJobInfo(string url, string filenameTemplate, Job.JobInfo jobInfo, params Browser[] browsers)
        {
            Contract.Requires(!string.IsNullOrEmpty(url));
            Contract.Requires(!string.IsNullOrEmpty(filenameTemplate));
            Contract.Requires(!illegalFileNameCharactersRegex.IsMatch(filenameTemplate), "The filename contains illegal characters.");
            Contract.Requires(jobInfo != null);
            Contract.Requires(browsers != null);
            Contract.Requires(browsers.Length > 1);

            this.Url      = url;
            this.Filename = filenameTemplate;
            this.JobInfo  = jobInfo;
            this.Browsers = browsers;
        }
Example #4
0
        /// <summary>
        /// Starts a BrowserStack screenshot job asynchronously.
        /// </summary>
        /// <param name="url">The url for which screenshots are required.</param>
        /// <param name="jobInfo">The job information that will be used to start the job.</param>
        /// <param name="usingTunnel">set to <c>true</c> if the BrowserStack jobs need to run under a tunnel. The tunnel must have been initiated externally.</param>
        /// <param name="browsers">The browsers that will be used to start the job.</param>
        /// <returns>
        /// The <see cref="Task" />.
        /// </returns>
        /// <exception cref="ApplicationException">Thrown when the call to the BrowserStack API results in an http code other than 200 (OK).</exception>
        public async Task <Job> StartJobAsync(string url, Job.JobInfo jobInfo, bool usingTunnel = false, params Browser[] browsers)
        {
            var jobRequest = new ScreenshotJobRequest()
            {
                url          = url,
                callback_url = jobInfo.CallbackUrl,
                orientation  = jobInfo.Orientation.HasValue ? jobInfo.Orientation.ToString().ToLower() : null,
                quality      = jobInfo.Quality.HasValue ? jobInfo.Quality.ToString().ToLower() : null,
                wait_time    = jobInfo.WaitTime,
                mac_res      = jobInfo.OsxResolution.HasValue ? jobInfo.OsxResolution.ToString().ToLower().Replace("r_", string.Empty) : null,
                win_res      = jobInfo.WinResolution.HasValue ? jobInfo.WinResolution.ToString().ToLower().Replace("r_", string.Empty) : null,
                tunnel       = usingTunnel,
                browsers     = browsers.Select(x => new BrowserInfo()
                {
                    browser = x.BrowserName, browser_version = x.BrowserVersion, device = x.Device, os = x.OS, os_version = x.OSVersion,
                }).ToArray()
            };

            using (var httpClient = this.httpClientFactory.Invoke())
            {
                var request = new HttpRequestMessage(HttpMethod.Post, screenshotsRestAPIBaseUrl)
                {
                    Content = new StringContent(JsonConvert.SerializeObject(jobRequest), Encoding.Default, "application/json")
                };
                if (this.AuthenticateForStartJob)
                {
                    request.Headers.Authorization = this.GetAuthenticationHeader();
                }

                var response = await httpClient.SendAsync(request);

                var responseString = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    throw new ApplicationException(
                              string.Format("Error while starting the job.\nResponse status is {0} ({1}).\nResponse is: {2}", response.ReasonPhrase, response.StatusCode, responseString));
                }

                var screenshotJob = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject <ScreenshotJob>(responseString));

                return(MapToJob(screenshotJob));
            }
        }
Example #5
0
        /// <summary>
        /// The create screenshot directory.
        /// </summary>
        /// <param name="jobInfo">The job info.</param>
        /// <param name="browser">The browser.</param>
        /// <param name="rootPath">The root path.</param>
        /// <returns>
        /// The <see cref="DirectoryInfo" />.
        /// </returns>
        private DirectoryInfo CreateScreenshotDirectory(Job.JobInfo jobInfo, Browser browser, string rootPath)
        {
            const string deviceFolderStructureTemplate  = @"{0}\{1}\{2}\{3}";
            const string browserFolderStructureTemplate = @"{0}\{1}\{2}\{3}\{4}";

            string screenshotFolderName;

            if (string.IsNullOrEmpty(browser.Device))
            {
                screenshotFolderName = string.Format(
                    browserFolderStructureTemplate,
                    browser.OS,
                    browser.OSVersion,
                    browser.BrowserName,
                    browser.BrowserVersion,
                    (browser.OS.ToLower().Contains("os x") ? jobInfo.OsxResolution.ToString() : jobInfo.WinResolution.ToString()).Replace("R_", string.Empty));
            }
            else
            {
                screenshotFolderName = string.Format(deviceFolderStructureTemplate, browser.OS, browser.OSVersion, browser.Device, jobInfo.Orientation);
            }

            return(Directory.CreateDirectory(Path.Combine(rootPath, screenshotFolderName)));
        }
Example #6
0
        /// <summary>
        /// Starts a BrowserStack screenshot job synchronously.
        /// </summary>
        /// <param name="url">The url for which screenshots are required.</param>
        /// <param name="jobInfo">The job information that will be used to start the job.</param>
        /// <param name="usingTunnel">set to <c>true</c> if the BrowserStack jobs need to run under a tunnel. The tunnel must have been initiated externally.</param>
        /// <param name="browsers">The browsers that will be used to start the job.</param>
        /// <returns>
        /// The <see cref="Job" />.
        /// </returns>
        /// <exception cref="ApplicationException">Thrown when the call to the BrowserStack API results in an http code other than 200 (OK).</exception>
        public Job StartJob(string url, Job.JobInfo jobInfo, bool usingTunnel = false, params Browser[] browsers)
        {
            var startJobAsync = StartJobAsync(url, jobInfo, usingTunnel, browsers);

            return(startJobAsync.GetAwaiter().GetResult()); //To properly re-throw an exception: http://stackoverflow.com/questions/20170527/how-to-correctly-rethrow-an-exception-of-task-already-in-faulted-state
        }