How to Integrate Sauce Labs Reports with MSTest and Jenkins

March 13th, 2014 by Amber Kaplan

Ever wondered how to integrate Sauce Selenium Testing with Jenkins? Yup, there’s a plugin for that.

But as many have discovered, the Sauce OnDemand plugin for Jenkins requires a bit of finessing in order to work with MSTest. One customer, Victor, was kind enough to share this issue and his solution with the web:

“The challenge that I’ve found with that is that the plugin is only for JUnit like tests, so, as we’re a .NET shop and we use MSTest to run automated builds, the plugin does not work completely out-of-the-box. Specifically the reporting part, as it takes an “.xml” (JUnit like) test results file and parses the console output of the tests looking for an specific SauceLabs ID to link tests back to SauceLabs jobs (More details: Integrating tests with the Sauce OnDemand plugin for Jenkins).

- Victor Pascual, Testing Island, February 17, 2014

Victor walks you through all the details with instructions and screenshots in his full post, here. Other useful tips, curated by Victor:

Definitely worth a read!

Guest Post: Designing a Ruby-based Sauce Test Automation Framework Pt. 2

March 12th, 2014 by lauren nguyen

Designing a Ruby-based Sauce Test Automation Framework – Implementing it on Ruby using Page Object Pattern 

In the first part of this blog series, we defined Page Object Pattern and also familiarized ourselves with the various building blocks of the Ruby-based test automation framework.

Now that, we have realized the benefits of using such a framework, let us try implementing a Simple Test Framework on Ruby using Page Object Pattern.

Implementing a Simple Test Framework on Ruby using Page Object Pattern

In the following section, we will implement a simple Selenium test framework using Page object pattern. Our framework contains Base classes for Test, Action, Page and Page element objects.

Next, we will write a few very simple test cases for:

  1. Verifying the page title on a web page
  2. b.     Test a form by filling the data elements in the form and testing a successful submit.

 

Test Base Class

First, let’s do a walkthrough of the Test Base class.

  1. Include the Selenium-webdriver Rubygem which is used to connect the testing framework with Selenium web driver.
  2. The start_browser() function invokes the Firefox browser with required options such as OS type, browser version, etc.

Please Note: For testing purposes we have set the default browser as Firefox on Linux, but we can make this dynamic by passing the corresponding parameters.

  1. This class also has other utility functions such as
    1. get_data() – to make Database connections and retrieve data
    2. launch_url() – to launch a new URL on the browser
    3. switch_to_frame() – to switch between active frames / windows.
require 'rubygems'
require 'selenium-webdriver'

class SeleniumTestBase

  def initialize (webDriver)
    @driver = webDriver
  end

  #this function starts the selenium webDriver on Firefox browser type
  #we can make it dynamic by using the params

  def start_browser(browser_type,platform,version)

    caps = Selenium::WebDriver::Remote::Capabilities.firefox
    caps.version = "5"
    caps.platform = :LINUX
    caps[:name] = "Testing Selenium 2 with Ruby on SauceLabs Environment"

    @driver = Selenium::WebDriver.for(
      :remote,
      :url => "<Use SauceLabs URL with appropriate key>",
      :desired_capabilities => caps
    )
  end

  def switch_to_window(handle)
    @driver.switch_to.window handle
  end

  def switch_to_frame (handle)
    @driver.switch.frame handle
  end

  def launch_url ( url)
    @driver.navigate.to url
  end

  def get_data(conn_string,sql1 )
    #some sql statements
  end

  def refresh
    @driver.get @driver.url
  end

  def teardown
    @driver.quit
  end
end

Please note one of the advantages of writing a separate Test Base class is that it uses the underlying driver implementation from the Test cases. Therefore, if we want to experiment with a new Driver version or even a completely new Driver, then the TestBase is the only class that will change leaving other parts of the framework untouched.

In a later section, we will show how one can create a project specific TestBase class which extends the main TestBase class. This will allow individual project teams to make project specific changes to the base class.

Action Base Class

Actions Base classes are responsible for the following:

  1. Executing steps required to run the test
  2. Inserting / Updating data elements and changing the state of the application while executing the test
  3. Reverting the changes made during the tests (for eg., rolling back the changes made on the database)
  4. Page operations such as navigating to a page, refreshing, switching across different frames and windows, etc.
class SeleniumActionBase

  def initialize (webDriver)
    @driver =  webDriver
  end

  def get_data(conn_string,sql1 )
    #connect to db
    #execute sql to retrieve data
  end

  def start_browser(browser_type)
    #override
  end

  def switch_to_window(handle)
    #override
  end

  def switch_to_frame (handle)\
    #override
  end

  def launch_url (url)
    #override
  end

  def refresh
    #override
  end
end

Page Base Class

The Page Class refers to actual web pages on the application that we want to test and essentially consists of a group of Page Elements. This class also defines a variable called BrowserIndex. Different browsers implement the locator start indexes differently and this variable can be used to handle the different implementations based on the browser type.

class SeleniumPageBase

  attr_reader :browserIndex

  def initialize ( webDriver)
    @driver = webDriver
    @browserIndex  = 1
  end

end

Page Element Base Class

The Page Element class is responsible for the following:

  1. Handle the actual interactions between the tests and the web pages.
  2. Wait for a particular page element to load (especially in case of Ajax)
  3. Provide specific error messages to describe why a particular page interaction failed.

 

class SeleniumPageElement

  def initialize(webDriver)
    @driver = webDriver
  end

  def waiting_get(seconds = 5, errorMessage = "")
    wait = Selenium::WebDriver::Wait.new(:timeout => seconds)
    wait.until { @myDriver.find_element(:id, @myBy) }
  end

  def click(seconds = 5, errorMessage = "")
    waiting_get(seconds, errorMessage).click();
  end

  def load_element(locator,val,errorMessage ='')
    @myBy = locator
    @element = find_element_id
    @element.send_keys val
  end

  def submit
    @element.submit
  end

  def get_response
    @driver.find_element(:id, 'your_comments')
  end

  protected

  def find_element_id
    begin
      return  @driver.find_element(:id, @myBy)
    rescue  Exception=>e
      raise e
    end
  end
end

 

(In our next blog in this series, we would see how we can build a test project using this framework)

References:

http://sauceio.com/index.php/2011/11/selenium-testing-framework-pt-2-base-classes/

This guest blog post was written by Vinodh Balaji Sridharan and Ganesh Kaliannan, Neev Technologies

Getting Started With Selenium – Chapter 6: Packaging for Use

March 11th, 2014 by Bill McGee

selenium-logo-160x144This post is the sixth in a series of “Getting Started with Selenium Testing” posts from Dave Haeffner, a noted expert on Selenium and automated testing, and a frequent contributor to the Sauce blog and Selenium community. This series is for those who are brand new to test automation with Selenium and a new chapter will be posted every Tuesday (eight chapters in all).

Packaging For Use

In order to get the most out of our tests and page objects, we’ll need to package them into a more useful structure.

Let’s do that using the examples from the previous write-ups.

Global Setup And Teardown

First we’ll need to pull the test setup and teardown actions out of our tests and into a central place. In RSpec this is straight-forward through the use of a ‘spec_helper’ file.

# filename: spec_helper.rb

require 'selenium-webdriver'

RSpec.configure do |config|

  config.before(:each) do
    @driver = Selenium::WebDriver.for :firefox
  end

  config.after(:each) do
    @driver.quit
  end

end

We need to include the Selenium library here, and by doing so, can remove it from our tests. And by having our test configuration here, we can remove it from the `before(:each)` and `after(:each)` in our tests as well — replacing them with a simple require statement at the top of the file (`require_relative ‘spec_helper’`).

Base URL

Rather than hard-coding a URL in our tests and page objects, We’ll want to put it someplace central, and we’ll want it to be configurable. So let’s create a ‘config.rb’ file in the parent directory and place it there.

# filename: config.rb

ENV['base_url'] ||= 'http://the-internet.herokuapp.com'

By using a conditional when setting the environment variable (`||=`) we are making it so we can override this value when launching our test suite (e.g., `base_url=’http://localhost:4567′`). It essentially means if the environment variable already exists and contains a value, use it. Otherwise, set it to ‘http://the-internet.herokuapp.com’. We can then reference this variable in our page objects where necessary (if we haven’t already).

For instance:

# filename: login.rb

class Login
...

def initialize(driver)
@driver = driver
@driver.get ENV['base_url'] + '/login'
end

...

Folder Organization

It’s about time we create some folders for our specs and page objects. To err on the side of simplicity, let’s call the folders ‘spec’ (for our tests) and ‘pages’ (for our page objects). We are using ‘spec’ since it is a default folder that RSpec will look for.

Here’s everything we should have after creating folders and moving files around:

.
|-- config.rb
|-- Gemfile
|-- pages
| |-- dynamic_loading.rb
| `-- login.rb
`-- spec
|-- dynamic_loading_spec.rb
|-- login_spec.rb
`-- spec_helper.rb

Updating Require Statements

As a result of doing this, we will need to update the require statements in our tests.

# filename: spec/login_spec.rb

require_relative 'spec_helper'
require_relative '../pages/login'

describe 'Login' do
...

# filename: spec/dynamic_loading_spec.rb

require_relative 'spec_helper'
require_relative '../pages/dynamic_loading'

describe 'Dynamic Loading' do
...

Note the use of double-dots (`..`) in the page object require statement. This is how we tell Ruby to traverse up a directory (from our spec directory) before trying to access the page objects folder. The `spec_helper` require remains unchanged since this file lives in the same directory as our tests.

Running Everything

Now that things are cleaned up, we can run everything. To do that we’ll want to make sure to include our new config file. We can do that by specifying it at run time with `rspec –require ./config.rb`, or, `rspec -r ./config.rb` (for short).

Note the `./` before `config.rb`. This tells RSpec that the config file is in the current directory.

Give it a shot. All of the tests should run and pass.

For more examples like this (along with complete working code) — grab your copy of  The Selenium Guidebook.

Previous Chapters: 1. Getting Started | 2. Writing a Good Acceptance Test | 3. Writing Your First Selenium Test | 4. How To Reuse Your Test Code | 5. Writing Resilient Test Code

Dave is the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by hundreds of testing professionals) as well as a new book, The Selenium Guidebook. He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.

Non-ASCII Characters in Appium, Part 1

March 10th, 2014 by Isaac Murchie

English is not the only language in the world. This should not be news. It should also not be news that people would like to test their apps with input from different languages. The good news is that both main mobile environments, iOS and Android, and their emulators, can handle Unicode text internally.

Non-ASCII text in Android EmulatorNon-ASCII text in iOS Simulator

Unfortunately, the mobile device emulators generally don’t play well with input of characters outside of the ASCII range. Which is to say, they have a hard time dealing with anything that is not English and a very small number of other characters (!#%…). The emulators can use the text, they just have some issues with getting it into the system. Below is a brief discussion on testing non-ASCII characters for each.

iOS

iOS, generally, plays better with text than Android: the simulator can manually handle the full range of Unicode characters, whether through a different keyboard or by pasting text into the appropriate field. Programmatically, however, the system cannot deal with characters not available in the default iOS keyboard. Sending the character é, for instance, will result in an error target.frontMostApp().keyboard() failed to locate key 'é'.

This is not good for automated testing.

Appium gets around this by sending the non-ASCII text directly to the text element, thus bypassing the keyboard altogether. Unfortunately, this can potentially interact badly with some applications, if they are expecting input character-by-character (e.g., predictive autocomplete).

One main caveat to this behavior is the encoding of the strings sent and received. Many strings will work without problems, such as sending “परीक्षण” (“testing” in Sanskrit). But Unicode also has the concept of “combining characters”, which are diacritical modifications of other characters. Rather than a single character representing what is seen, two (or more, in the case of heavily accented characters) separate characters are used to represent one, with the system overlaying them.

Thus, while in Unicode the letter é (called “LATIN SMALL LETTER E WITH ACUTE”) can be encoded as a single letter, the iOS simulator will return the equally valid representation of the letter e followed by the accent, ́, which the Unicode Consortium calls a “COMBINING ACUTE ACCENT”. Therefore to test equality you may need to account for that difference, by normalizing the input and output (for an example in JavaScript, see accent_specs.js). The symptom of this kind of error will generally be an error condition with the expected and actual text seemingly exactly the same. Non-normalized combining characters failing By normalizing the text this seemingly erroneous error ought to go away.

Android

On the other hand, the Android Emulator does not work so easily. Manually, one can change keyboards and then type using it. When automating tests, however, this is more difficult. Theoretically it is possible to install the keyboard for your target language, and then send the text to that. The problem with this is that your tests will not be able to set the text in the element, but rather need to simulate the keystrokes, with meta-keys and all. The text input method will only accept ASCII characters, no matter what.

The Appium team is working on an experimental solution to the situation on Android, marshaling an ASCII encoding of the Unicode text into the Android emulator. We are currently testing the solution.

We look forward to making Appium even more useful for your mobile testing. Stay tuned for Part 2, coming soon, with details on making testing Android through Appium mutlilingual!

Introducing ShotsOnSauce by Jim Eisenhauer

March 7th, 2014 by Amber Kaplan

Here at Sauce Labs, we’re all about open source, collaboration, and hacks – so when we learned about ShotsOnSauce, we did a happy dance. From the interwebz:

“Do you ever find yourself opening 10 different browsers on 4 different machines just so you can see how a new static ‘marketing’ page will look or what has changed in each of these browsers?

Well I do, and I figured there had to be a better way.  Two of my favorite things on the internet are github.com & saucelabs.com.  I figured between these tools there has to be a solution.”

Jim Eisenhaur, jameseisenhauer.com, January 25, 2014

Seeing as there wasn’t an existing solution, Jim created open source tool ShotsOnSauce. Now you can grab the screenshots from all the browsers and OS platforms you want using Sauce and compare them using the little known image diff feature on Github.

Jim thinks there are a good chunk of you out there who might need this tool, and we couldn’t agree more.

Check out the full post by the genius behind the tool, Jim Eisenhauer, for the how-to right here.

You can download ShotsOnSauce on Github here. Did we mention it’s open source yet?! Feel free to contribute to improve it.

About Jim Eisenhauer

Jim Eisenhauer is the Quality Engineer at Portland Oregon based start-up hubbub health and the curator of the Portland Selenium Meetup.

Online Workshop – Testing Behind a Firewall

March 6th, 2014 by Amber Kaplan

Learn all about best practices and strategies for testing apps behind a firewall and how to use Sauce Connect during our next online workshop! Join speaker Mike Redman, Director of Sales Engineering at Sauce, on Tuesday, March 11, 2014, at 11:00 AM Pacific Time for the latest.

Whether you’re at the enterprise or startup level, security is a hot topic. That’s why we created Sauce Connect. Sauce Connect creates a secure tunnel between your firewalled app and the Sauce cloud so you can run your tests knowing that your data is encrypted through industry standard TLS.

Keeping our security standards in mind, we completely rewrote the app. With the launch of our latest version, Sauce Connect 4, your tests will now run faster than ever, even with heavy loads. It’s better performing, more reliable, and gives broader support for a wider range of web standards, including Websockets.

Mike will walk you through testing behind a firewall and how to use Sauce Connect 4.  A live Q&A session will follow.  Register today!

Guest Post: Designing a Ruby-based Sauce Test Automation Framework

March 5th, 2014 by lauren nguyen

Designing a Ruby-based Sauce Test Automation Framework – The What and the Why

When we start developing regression test suites for our codebase, we encounter issues such as code duplication, repetition of setup code, searching for required section of code from actual test code, managing different layers of tests such as field level, section level, page level and application level test code. A good test automation framework is built keeping the above design issues in mind.

In this blog, we will cover why we should use Page Object Pattern, a design pattern in a test automation framework. We will then create a simple test suite in Ruby to implement this pattern and try executing it on Saucelabs.

The Page Object Pattern Defined:

Every test code that you write will comprise of several components – first the code needed to navigate through and interact with the elements of the page that you want to test. Then, there is the actual test code itself that reviews the content of the page and verifies if the actual results seen on the page matches with the expected results.

The architecture of this framework comprises of the following building blocks:

  1. Tests
  2. Actions
  3. Pages
  4. Page Elements

Base class

Description

SeleniumTest

This class requires all the basic methods to start the environment for testing.This class has intializer in which it is possible to specify the Driver TypeIt has method to create browser instance, launch a specific URL in that instance, it can establish connection with database if required, and can switch between frames and windows.

This class can also refresh a current URL.

SeleniumAction

  1. This class needs to interact with the pages components and get the task completed.
  2. This class can change the pages in the browser or can also bring back the previous status of the pages in the browser.
  3. It also interacts with database for various inputs required in pages. And this class can also switch frames and windows.

SeleniumPages

  1. This class is required by both the above class to perform changes. This is to represent the page which is used by both Action and Test class.
  2. This class is used to facilitate locating a specific element on a page, one of the ways for which could be to use browser start index and for that it has to know the browser being used.

SeleniumPageElement

  • This class is required to identify elements on the pages, which are used by actions and tests. This class will identify elements based on id or css or xpath provided by the user and return it to actions and tests.
  • This class can also click a specific element and can wait for some element to appear on the page.

Class Diagram:

  Selenium class diagram

Advantages

The advantage of using such a framework is the clear segregation of the functions across the various classes. For instance, now our Test classes will only have to verify and assert test conditions. While the Action classes will handle the required action steps to be taken on the page such as retrieving values or inserting / updating values to change the current state of the system. And the Page classes will manage the interactions of the elements within it with the help of Action or Test classes. This framework also offers the advantages of reusability and maintainability of the test codebase in the long run.

(In our further blogs in this series, we will look at implementing a Simple Test Framework on Ruby using Page Object Pattern. We will also write a few simple test cases.)

References:

  • http://saucelabs.com/blog/index.php/2011/11/selenium-testing-framework-pt-1-testing-concepts/

This guest post was written by Vinodh Balaji Sridharan and Ganesh Kaliannan, Neev Technologies

Getting Started with Selenium: Chapter 5 – Writing Resilient Test Code

March 4th, 2014 by Bill McGee

selenium-logo-160x144This post is the fifth in a series of “Getting Started with Selenium Testing” posts from Dave Haeffner, a noted expert on Selenium and automated testing, and a frequent contributor to the Sauce blog and Selenium community. This series is for those who are brand new to test automation with Selenium and a new chapter will be posted every Tuesday (eight chapters in all).

Writing Resilient Test Code

Ideally, you should be able to write your tests once and run them across all supported browsers. While this is a rosy proposition, there is some work to make this a reliable success. And sometimes there may be a hack or two involved. But the lengths you must go really depends on the browsers you care about and the functionality you’re dealing with.

By using high quality locators you will be well ahead of the pack, but there are still some persnickity issues to deal with. Most notably – timing. This is especially true when working with dynamic, JavaScript heavy pages (which is more the rule than the exception in a majority of applications you’ll deal with).

But there is a simple approach that makes up the bedrock of reliable and resilient Selenium tests — and that’s how you wait and interact with elements. The best way to accomplish this is through the use of explicit waits.

An Example

Let’s step through an example that demonstrates this against a dynamic page on the-internet. The functionality is pretty simple — there is a button. When you click it a loading bar appears for 5 seconds, then disappears, and gets replaced with the text ‘Hello World!’.

Let’s start by looking at the markup on the page.

Dynamically Loaded Page Elements

Example 1: Element on page that is hidden


At a glance it’s simple enough to tell that there are unique idattributes that we can use to reference the start button and finish text. Let’s add a page object for Dynamic Loading.

Part 1: Create A Page Object

# filename: dynamic_loading.rb

class DynamicLoading

  START_BUTTON  = { css: '#start button' }
  FINISH_TEXT   = { id: 'finish' }

  def initialize(driver)
    @driver = driver
    @driver.get "http://the-internet.herokuapp.com/dynamic_loading/1"
  end

  def start
    @driver.find_element(START_BUTTON).click
  end

  def finish_text_present?
    wait_for { is_displayed? FINISH_TEXT }
  end

  def is_displayed?(locator)
    @driver.find_element(locator).displayed?
  end

  def wait_for(timeout = 15)
    Selenium::WebDriver::Wait.new(:timeout => timeout).until { yield }
  end

end

This approach should look familiar to you if you checked out the last write-up. The thing which is new is the wait_for method. In it we are using a built-in Selenium wait action. This is the mechanism with which we will perform explicit waits.

More On Explicit Waits

It’s important to set a reasonably sized default timeout for the explicit wait. But you want to be careful not to make it too high. Otherwise you run into a lot of the same timing issues you get from implicit waits. But set it too low and your tests will be brittle, forcing you to run down trivial and transient issues.

In our page object when we’re usingwait_for { is_displayed? FINISH_TEXT } we are telling Selenium to to see if the finish text is displayed on the page. It will keep trying until it either returns true or reaches fifteen seconds — whichever comes first.

If the behavior on the page takes longer than we expect (e.g., due to slow inherently slow load times), we can simply adjust this one wait time to fix the test (e.g.,wait_for(30) { is_displayed? FINISH_TEXT }) — rather than increase a blanket wait time (which impacts every test). And since it’s dynamic, it won’t always take the full amount of time to complete.

Part 2: Write A Test To Use The New Page Object

Now that we have our page object we can wire this up in a new test file.

# filename: dynamic_loading_spec.rb

require 'selenium-webdriver'
require_relative 'dynamic_loading'

describe 'Dynamic Loading' do

  before(:each) do
    @driver = Selenium::WebDriver.for :firefox
    @dynamic_loading = DynamicLoading.new(@driver)
  end

  after(:each) do
    @driver.quit
  end

  it 'Waited for Hidden Element' do
    @dynamic_loading.start
    @dynamic_loading.finish_text_present?.should be_true
  end

end

When we run it (rspec dynamic_loading_page.rb from the command-line) it should pass, rather than throwing an exception (like in the last write-up when the element wasn’t present).

As an aside — an alternative approach would be to rescue the exception like this:

  def is_displayed?(locator)
    begin
      @driver.find_element(locator).displayed?
    rescue Selenium::WebDriver::Error::NoSuchElementError
      false
    end
  end

This would enable you to check the negative condition for whether or not an element is displayed. And it can be used with an explicit wait as well (it won’t change it’s behavior).

Part 3: Add A Second Test

Let’s step through one more dynamic page example to see if our explicit wait approach holds up.

Our second example is laid out similarly to the last one, the main difference is that it will render the final result after the progress bar completes. Here’s the markup for it.

Dynamically Loaded Page Elements

Example 2: Element rendered after the fact



In order to find the selector for the finish text element we need to inspect the page after the loading bar sequence finishes. Here’s what it looks like.

Hello World!

Before we add our test, we need to modify our page object to accommodate visiting the different example URLs.

# filename: dynamic_loading.rb

class DynamicLoading

  START_BUTTON  = { css: '#start button' }
  FINISH_TEXT   = { id: 'finish' }

  def initialize(driver)
    @driver = driver
  end

  def visit_example(example_number)
    @driver.get "http://the-internet.herokuapp.com/dynamic_loading/#{example_number}"
  end

  ...

Now that we have that sorted, let’s add a new test to reference the markup shown above (and update our existing test to use the new.visit_example method).

# filename: dynamic_loading_spec.rb


require_relative 'dynamic_loading'

describe 'Dynamic Loading' do

  ...

  it 'Waited for Hidden Element' do
    @dynamic_loading.visit_example 1
    @dynamic_loading.start
    @dynamic_loading.finish_text_present?.should be_true
  end

  it 'Waited for Element To Render' do
    @dynamic_loading.visit_example 2
    @dynamic_loading.start
    @dynamic_loading.finish_text_present?.should be_true
  end

end

If we run these tests (rspec dynamic_loading_spec.rb from the command-line) then the same approach will work for both cases.

Explicit waits are one of the most important concepts in testing with Selenium. Use them often.

For a more in-depth look at explicit waits and how to address cross-browser timing issues — grab your copy of The Selenium Guidebook.

Previous Chapters: 1. Getting Started | 2. Writing a Good Acceptance Test | 3. Writing Your First Selenium Test | 4. How To Reuse Your Test Code

Dave is the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by hundreds of testing professionals) as well as a new book, The Selenium Guidebook. He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.

Testing Mobile Apps? Win an iPad!

March 3rd, 2014 by Amber Kaplan

phoneSauce Labs is all about keeping it real, so naturally we’re adding real devices to our mobile cloud!

So we don’t accidentally participate in an episode of When Keeping It Real Goes Wrong, we’d like to learn more about how you’re doing mobile testing. Help us by filling out this short survey. Uh, did we mention our sweet deal yet? 1 out of every 100 participants will win an iPad Mini. Tell your friends!

Be sure to check back here or follow us on Twitter, Google+, LinkedIn, or Facebook for news about our imminent real devices launch.

Bleacher Report Uses Appium by Sauce to Achieve “Olympic Quality” Results to Win at QA Testing (VIDEO)

February 28th, 2014 by Amber Kaplan

It’s an Olympic year, and Bleacher Report gets the gold when it comes to QA mobile testing. Winning!

Bleacher Report is a digital media company that delivers engaging content to sports fans all over the world. With more than half of their traffic coming from mobile devices, the team knew they needed to find a way to automatically test their mobile apps and mobile web experience. So they turned to Sauce Labs and Appium. Check out the video below to learn more.

Are you using Appium to test all your things? We’d love to hear what you’re working on. Leave us a comment on this post, tweet at us, or sign up for a free Sauce account to start testing.