Code Monkey home page Code Monkey logo

saucerest-java's Introduction

saucerest-java Logo

saucerest-java

GitHub release (latest by date) CI/CD Codecov Maven


A Java client for Sauce Labs REST API.

Currently, this client only support the endpoints listed here.

With version 2.x of SauceREST we have made code-breaking changes to this wrapper. It has been updated to be more future-proof and to also support the newest APIs from Sauce Labs.

This is going to be continuous process which means we will release changes to SauceREST over time.

If a function you're after isn't supported, we suggest either shelling out and using the curl version, or sending a pull request! Contribution Details Here.


How to use

Creating a client object
SauceREST sauceREST = new SauceREST("username", "access-key", DataCenter.EU_CENTRAL);

Parameters:

Name Type Details
username String (required) Your sauce labs username
access-key String (required) Your sauce labs accesskey
data_center String or DataCenter (required) One of US_WEST, EU_CENTRAL

Code examples

The best way to find out how to use this library is to look at the tests. They are located in the src/test/java directory. Especially the integration tests will provide you with a good overview of how to use this library.

Maven

<dependencies>
    <dependency>
        <groupId>com.saucelabs</groupId>
        <artifactId>saucerest</artifactId>
        <version>LATEST VERSION</version>
        <scope>test</scope>
    </dependency>
</dependencies>

For latest version please check the following link: click.

Contributing

Check out our contribution guide here for details.

Want a fast, setup dev environment? Open in Gitpod

saucerest-java's People

Contributors

adrian256 avatar alexh-sauce avatar basalt79 avatar bootstraponline avatar christian-bromann avatar dependabot[bot] avatar diemol avatar dylanlacey avatar guptaakshay avatar halkeye avatar imurchie avatar jlipps avatar joshgrantsauce avatar krzysieksulejczak avatar llaskin avatar maciejurbanskisaucelabs avatar purus avatar recampbell avatar romainlouvet avatar ronroche avatar rossrowe avatar santiycr avatar sceiler avatar seanenright avatar sstopkin avatar timja avatar titusfortner avatar valfirst avatar vickislobodeniuk avatar yfangsl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saucerest-java's Issues

Close stream of downloaded file

Would you mind adding a finally block to close the stream(s) to the file downloaded in downloadFile(), so that tests may opt to move/delete the file?

Replace HttpURLConnection with HttpClient

Description

With Java 11 there is a new Http client which adds more features and is in general easier to use than the decade old HttpURLConnection.

Motivation and Context

HttpURLConnection is more cumbersome to use and except the support for Java 1.4 does not really have any other benefits.

Further comments

SauceOnDemandTestWatcher doesn’t work

Here is my code:

package base;

import com.saucelabs.common.SauceOnDemandAuthentication;
import com.saucelabs.common.SauceOnDemandSessionIdProvider;
import com.saucelabs.junit.SauceOnDemandTestWatcher;
import com.saucelabs.saucerest.SauceREST;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.ios.IOSDriver;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.support.ui.WebDriverWait;
import view_objects.*;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import static base.PlatformType.*;
import static base.ServerType.*;
import static java.lang.String.format;
import static java.lang.System.getProperty;
import static java.lang.System.getenv;
import static java.lang.Thread.sleep;
import static org.junit.Assert.assertTrue;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;
import static test_utils.TestConstants.*;


public abstract class BasePreconditions implements SauceOnDemandSessionIdProvider {

    @Rule
    public TestName testName = new TestName();

    //SAUCELABS
    private static final String username = getenv("SAUCE_USERNAME");
    private static final String accessKey = getenv("SAUCE_ACCESS_KEY");
    private static final String sauceServer = "@ondemand.eu-central-1.saucelabs.com:443/wd/hub"; //EU Central 1
    private final SauceREST sauceAPI = new SauceREST(username, accessKey);
    private final SauceOnDemandAuthentication auth = new SauceOnDemandAuthentication(username, accessKey);

    protected AppiumDriver driver;
    protected PlatformType platform;
    protected ServerType server;
    private String sessionId;
    protected String baseAppiumUrl = "http://localhost:";
    protected String phoneNumber;
    protected String code;
    protected AndroidKey codeDigit1;
    protected AndroidKey codeDigit2;
    protected AndroidKey codeDigit3;
    protected AndroidKey codeDigit4;
    private WebDriverWait wait;

    protected MainView mainView;
    protected LoginViews loginViews;
    protected OrdersView ordersView;
    protected OrderGuideView orderGuideView;
    protected OrderGuideSearchView orderGuideSearchView;
    protected DeliveryDateView deliveryDateView;
    protected ReviewYourOrderView reviewYourOrderView;
    protected ForgetAnythingView forgetAnythingView;
    protected OrderSentView orderSentView;
    protected DoubleCheckDeliveryDateView doubleCheckDeliveryDateView;
    protected UploadOptionsView uploadOptionsView;
    protected UploadImagesView uploadImagesView;
    protected AddImageView addImageView;
    protected AddProductDetailsView addProductDetailsView;
    protected EditProductView editProductView;
    protected ChatView chatView;
    protected ChatSettingsView chatSettingsView;
    protected ContactsView contactsView;
    protected InviteContactView inviteContactView;
    protected SelectChatsView selectChatsView;
    protected NewMemberInvitedView newMemberInvitedView;
    protected UserRemovedFromChatView userRemovedFromChatView;
    protected UserRemovedFromLocationView userRemovedFromLocationView;
    protected NewStableBuildAvailableView newStableBuildAvailableView;
    protected ProductDetailsView productDetailsView;
    protected ProductsCatalogueView productsCatalogueView;
    protected UnitModalView unitModalView;
    protected ProductAddedView productAddedView;
    protected MarketView marketView;
    protected SpecialityView specialityView;
    protected PickLocationView pickLocationView;
    protected SupplierChatView supplierChatView;
    protected SupplierCardView supplierCardView;
    protected CatalogueItemsView catalogueItemsView;
    protected ReviewProductsView reviewProductsView;
    protected AllSuppliersView allSuppliersView;
    protected EnterSupplierDetailsView enterSupplierDetailsView;
    protected AddContactNumberView addContactNumberView;
    protected YouCanStartOrderingNowView youCanStartOrderingNowView;
    protected AndroidSelectPhotoView androidSelectPhotoView;
    protected SomethingWentWrongView somethingWentWrongView;
    protected CodeEntryView codeEntryView;
    protected SettingsView settingsView;
    protected NotificationSettingsView notificationSettingsView;
    protected IOSPhotosGalleryView iosPhotosGalleryView;
    protected OrderView orderView;
    protected ReportIssueToSupplierView reportIssueToSupplierView;
    protected ProductIssueView productIssueView;
    protected IssueDetailsView issueDetailsView;
    protected IssuesReportedToSupplierView issuesReportedToSupplierView;
    protected ReportedIssuesView reportedIssuesView;
    protected ReportedProductView reportedProductView;
    protected SelectFileView selectFileView;
    protected AddInvoiceView addInvoiceView;
    protected AddToOrderView addToOrderView;
    protected AddOrEditInvoiceDetailsView addOrEditInvoiceDetailsView;
    protected YourInvoiceWasAddedView yourInvoiceWasAddedView;
    protected UploadInvoiceView uploadInvoiceView;
    protected OpenedChatImagesView openedChatImagesView;
    protected LongPressOpenedChatImageView longPressOpenedChatImageView;
    protected AndroidShareView androidShareView;
    protected RecommendedProductsView recommendedProductsView;
    protected InvoiceLayoutView invoiceLayoutView;
    protected InvoiceForwardDownloadOptionsView invoiceForwardDownloadOptionsView;
    protected ManageLocationView manageLocationView;
    protected ManageTeamView manageTeamView;
    protected EnterRepDetailsView enterRepDetailsView;
    protected OrderForwardingView orderForwardingView;
    protected TrackOrdersView trackOrdersView;
    protected ProSupplierView proSupplierView;
    protected PaymentMethodView paymentMethodView;
    protected BillingAddressView billingAddressView;
    protected UserAgreementView userAgreementView;
    protected PaymentMethodsView paymentMethodsView;
    protected PickPaymentMethodView pickPaymentMethodView;
    protected RekkiSupportChatView rekkiSupportChatView;
    protected ImageUploadView imageUploadView;
    protected PaymentMethodsSettingsView paymentMethodsSettingsView;
    protected RateSuppliersServiceView rateSuppliersServiceView;
    protected SauceCameraAllowAccessView sauceCameraAllowAccessView;

    @Override
    public String getSessionId() {
        return sessionId;
    }

    @Rule
    public SauceOnDemandTestWatcher watcher = new SauceOnDemandTestWatcher(this, auth);

    @Rule
    public TestName name = new TestName() {
        public String getMethodName() {
            return format("%s", super.getMethodName());
        }
    };

    public BasePreconditions() {
        setPlatformType();
        setServerType();
    }

    private void setPlatformType() {
        String cliArg = getProperty("platformType");
        if (cliArg == null) {
            // default to ios if no one set the platform type
            cliArg = "ios";
        }
        if (cliArg.equalsIgnoreCase(ANDROID.name())) {
            platform = ANDROID;
        } else if (cliArg.equalsIgnoreCase(ANDROID_DEMO.name())) {
            platform = ANDROID_DEMO;
        } else if (cliArg.equalsIgnoreCase(ANDROID_DEMO_LOCAL_APK.name())) {
            platform = ANDROID_DEMO_LOCAL_APK;
        } else if (cliArg.equalsIgnoreCase(IOS.name())) {
            platform = IOS;
        } else {
            platform = IOS_DEMO;
        }
    }

    private void setServerType() {
        String serverArg = getProperty("serverType");
        if (serverArg == null) {
            // default to local if no one set the server type
            serverArg = "local";
        }
        if (serverArg.equalsIgnoreCase(SAUCE_WITH_APP_FROM_SERVER.name())) {
            if (username == null || accessKey == null) {
                System.out.println("Username and access key were not set; running locally");
                server = LOCAL;
                return;
            }
            server = SAUCE_WITH_APP_FROM_SERVER;
        } else if (serverArg.equalsIgnoreCase(SAUCE_WITH_APP_FROM_LOCAL.name())) {
            server = SAUCE_WITH_APP_FROM_LOCAL;
        } else {
            server = LOCAL;
        }
    }

    private String getAppFile(String app) {
        File file = new File("src/test/resources/apps/" + app);
        return file.getAbsolutePath();
    }

    protected MobileElement safeFindClickable(MobileElement mobileElement) {
        return (MobileElement) wait.until(elementToBeClickable(mobileElement));
    }

    protected MobileElement safeFindVisible(MobileElement mobileElement) {
        return (MobileElement) wait.until(visibilityOf(mobileElement));
    }

    protected void safeFindTextToBePresentInElement(MobileElement mobileElement, String text) {
        wait.until(textToBePresentInElement(mobileElement, text));
    }

    //EMU_1 device
    protected AppiumDriver getDriver(DriverFactory driverFactory) {
        if (testName.getMethodName().equals("smokeCloseAndReopenAppTest")
                || testName.getMethodName().equals("smokeLoadingAppInOfflineModeTest"))
            return driverFactory.getDriverNoReset(EMU_1, "8200", "iPhone 8", "8100");
        else return driverFactory.getDriver(EMU_1, "8200", "iPhone 8", "8100");
    }

    protected void login() throws InterruptedException {
        if (platform == ANDROID || platform == ANDROID_DEMO || platform == ANDROID_DEMO_LOCAL_APK) {
            loginViews.loginAndroid
                    (phoneNumber, codeDigit1, codeDigit2, codeDigit3, codeDigit4, (AndroidDriver) driver);
        } else {
            loginViews.loginIos(phoneNumber, code, (IOSDriver) driver);
        }
        boolean tryAgain = true;
        int retryCount = 0;
        while (tryAgain && retryCount < 5) {
            try {
                safeFindClickable(ordersView.selectLocationDropdownArrow).click();
                tryAgain = false;
            } catch (StaleElementReferenceException staleElementReferenceException) {
                assertTrue(rateSuppliersServiceView.header.isDisplayed() &&
                        rateSuppliersServiceView.header.getText().equals("RATE YOUR SUPPLIER’S SERVICE THIS WEEK"));
                rateSuppliersServiceView.clickOnSkipButton();
                retryCount += 1;
                tryAgain = true;
            }
        }
        ordersView.clickOnAppleTestLocation();
        ordersView.clickOnOrdersTab();
    }

    @Before
    public void setUp() throws IOException, InterruptedException {
        String app = getAppFile("Rekki Demo.zip");
        if (platform == ANDROID) {
            app = "https://unity.rekki.com/android-apks/rekki-live-release-" + getProperty("apkVersion") + ".apk";
        } else if (platform == ANDROID_DEMO) {
            app = "https://unity.rekki.com/android-apks/rekki-demo-release-" + getProperty("demoApkVersion") + ".apk";
        } else if (platform == ANDROID_DEMO_LOCAL_APK && server == LOCAL) {
            app = getAppFile("rekki-demo-release-" + getProperty("demoApkVersion") + ".apk");
        } else if (platform == IOS_DEMO) {
            app = getAppFile("Rekki Demo.zip"); //TODO update iOS when link will be provided
        }

        URL serverUrl = new URL(baseAppiumUrl);
        String appStr = app;

        if (platform == ANDROID_DEMO_LOCAL_APK && server == SAUCE_WITH_APP_FROM_LOCAL) { //upload app file from project dir
            serverUrl = new URL("https://" + username + ":" + accessKey + sauceServer);
            sauceAPI.uploadFile(new File(app)); //DEPRECATED
            appStr = "sauce-storage:" + app; //DEPRECATED
            //todo - LOCAL MODE
            /*
            * curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location \
                                                           --request POST 'https://api.eu-central-1.saucelabs.com/v1/storage/upload' \
                                                           --form 'payload=@"/Users/sasha/IdeaProjects/mobile_automation/src/test/resources/apps/rekki-demo-release-20.29.31.apk"' \
                                                           --form 'name="rekki-demo-release-20.29.31.apk"'
                                                           * TODO - later implement it via RestAssured
                                                           * */
        } else if (server == SAUCE_WITH_APP_FROM_SERVER) {
            serverUrl = new URL("https://" + username + ":" + accessKey + sauceServer);
            appStr = "https://unity.rekki.com/android-apks/rekki-demo-release-" + getProperty("demoApkVersion") + ".apk";
        }

        DriverFactory driverFactory = new DriverFactory(platform, server, appStr, serverUrl, name.getMethodName());
        driver = getDriver(driverFactory);
        sessionId = driver.getSessionId().toString();

        mainView = new MainView(driver);
        loginViews = new LoginViews(driver);
        ordersView = new OrdersView(driver);
        orderGuideView = new OrderGuideView(driver);
        orderGuideSearchView = new OrderGuideSearchView(driver);
        deliveryDateView = new DeliveryDateView(driver);
        reviewYourOrderView = new ReviewYourOrderView(driver);
        forgetAnythingView = new ForgetAnythingView(driver);
        orderSentView = new OrderSentView(driver);
        doubleCheckDeliveryDateView = new DoubleCheckDeliveryDateView(driver);
        uploadOptionsView = new UploadOptionsView(driver);
        uploadImagesView = new UploadImagesView(driver);
        addImageView = new AddImageView(driver);
        addProductDetailsView = new AddProductDetailsView(driver);
        editProductView = new EditProductView(driver);
        chatView = new ChatView(driver);
        chatSettingsView = new ChatSettingsView(driver);
        contactsView = new ContactsView(driver);
        inviteContactView = new InviteContactView(driver);
        selectChatsView = new SelectChatsView(driver);
        newMemberInvitedView = new NewMemberInvitedView(driver);
        userRemovedFromChatView = new UserRemovedFromChatView(driver);
        userRemovedFromLocationView = new UserRemovedFromLocationView(driver);
        newStableBuildAvailableView = new NewStableBuildAvailableView(driver);
        productDetailsView = new ProductDetailsView(driver);
        productsCatalogueView = new ProductsCatalogueView(driver);
        unitModalView = new UnitModalView(driver);
        productAddedView = new ProductAddedView(driver);
        marketView = new MarketView(driver);
        specialityView = new SpecialityView(driver);
        supplierChatView = new SupplierChatView(driver);
        supplierCardView = new SupplierCardView(driver);
        catalogueItemsView = new CatalogueItemsView(driver);
        reviewProductsView = new ReviewProductsView(driver);
        pickLocationView = new PickLocationView(driver);
        allSuppliersView = new AllSuppliersView(driver);
        enterSupplierDetailsView = new EnterSupplierDetailsView(driver);
        addContactNumberView = new AddContactNumberView(driver);
        youCanStartOrderingNowView = new YouCanStartOrderingNowView(driver);
        androidSelectPhotoView = new AndroidSelectPhotoView(driver);
        somethingWentWrongView = new SomethingWentWrongView(driver);
        codeEntryView = new CodeEntryView(driver);
        settingsView = new SettingsView(driver);
        iosPhotosGalleryView = new IOSPhotosGalleryView(driver);
        orderView = new OrderView(driver);
        reportIssueToSupplierView = new ReportIssueToSupplierView(driver);
        productIssueView = new ProductIssueView(driver);
        issueDetailsView = new IssueDetailsView(driver);
        issuesReportedToSupplierView = new IssuesReportedToSupplierView(driver);
        reportedIssuesView = new ReportedIssuesView(driver);
        reportedProductView = new ReportedProductView(driver);
        notificationSettingsView = new NotificationSettingsView(driver);
        selectFileView = new SelectFileView(driver);
        addInvoiceView = new AddInvoiceView(driver);
        addToOrderView = new AddToOrderView(driver);
        addOrEditInvoiceDetailsView = new AddOrEditInvoiceDetailsView(driver);
        yourInvoiceWasAddedView = new YourInvoiceWasAddedView(driver);
        uploadInvoiceView = new UploadInvoiceView(driver);
        openedChatImagesView = new OpenedChatImagesView(driver);
        longPressOpenedChatImageView = new LongPressOpenedChatImageView(driver);
        androidShareView = new AndroidShareView(driver);
        recommendedProductsView = new RecommendedProductsView(driver);
        invoiceLayoutView = new InvoiceLayoutView(driver);
        invoiceForwardDownloadOptionsView = new InvoiceForwardDownloadOptionsView(driver);
        manageLocationView = new ManageLocationView(driver);
        manageTeamView = new ManageTeamView(driver);
        enterRepDetailsView = new EnterRepDetailsView(driver);
        orderForwardingView = new OrderForwardingView(driver);
        trackOrdersView = new TrackOrdersView(driver);
        proSupplierView = new ProSupplierView(driver);
        paymentMethodView = new PaymentMethodView(driver);
        billingAddressView = new BillingAddressView(driver);
        userAgreementView = new UserAgreementView(driver);
        paymentMethodsView = new PaymentMethodsView(driver);
        pickPaymentMethodView = new PickPaymentMethodView(driver);
        rekkiSupportChatView = new RekkiSupportChatView(driver);
        imageUploadView = new ImageUploadView(driver);
        paymentMethodsSettingsView = new PaymentMethodsSettingsView(driver);
        rateSuppliersServiceView = new RateSuppliersServiceView(driver);
        sauceCameraAllowAccessView = new SauceCameraAllowAccessView(driver);

        wait = new WebDriverWait(driver, 15);

        if (testName.getMethodName().equals("smokeCloseAndReopenAppTest")
                || testName.getMethodName().equals("smokeLoadingAppInOfflineModeTest")) {
            driver.resetApp(); //VERY IMPORTANT PRECONDITION FOR OFFLINE/RESET SCENARIO TESTS
            sleep(5_000);
        }

        sleep(5_000); //waiting for splash screen animation to disappear todo - investigate to avoid this sleep

        safeFindClickable(mainView.loginButton).click();
        if (!testName.getMethodName().equals("smokeLoginNegativeTest")) {
            login();
        } else {
            if (platform == ANDROID || platform == ANDROID_DEMO || platform == ANDROID_DEMO_LOCAL_APK) {
                loginViews.loginAndroidNegative(PHONE_NUMBER, (AndroidDriver) driver);
            } else {
                loginViews.loginIosNegative(PHONE_NUMBER, CODE_NEGATIVE, (IOSDriver) driver);
            }
        }
    }

    @After
    public void tearDown() {
        driver.quit();
    }
}

It doesn’t listen to my tests running and send status passed/failed to SauceLabs

cc @jlipps , I used your guide Getting Started With Appium - Java Edition.pdf
Getting Started With Appium - Java Edition.pdf

but it doesn’t work for me

image

image

Fix javadoc generating warning and errors

When running mvn clean install or more specifically mvn org.apache.maven.plugins:maven-javadoc-plugin:3.1.0:jar it will fail with this error:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.089 s
[INFO] Finished at: 2020-10-05T17:51:57+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.1.0:jar (default-cli) on project saucerest: MavenReportException: Error while generating Javadoc:
[ERROR] Exit code: 1 - javadoc: error - The code being documented uses modules but the packages defined in https://docs.oracle.com/javase/8/docs/api/ are in the unnamed module.
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceException.java:13: warning: no @param for message
[ERROR] public SauceException(String message) {
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:203: warning: no @param for endpoint
[ERROR] protected URL buildEDSURL(String endpoint) {
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:332: error: no tag name after @
[ERROR] * @// TODO: 27/2/20 I think this should be called "downloadVideo" and "attemptVideoDownload" should be the silent failure method - Dylan
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:366: error: no tag name after @
[ERROR] * @// TODO: 27/2/20 I think this should be called "attemptLogDownload" - Dylan
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:382: error: no tag name after @
[ERROR] * @// TODO: 27/2/20 I think this should be called "downloadLog" and "attemptLogDownload" should be the silent failure method - Dylan
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:411: error: no tag name after @
[ERROR] * @// TODO: 27/2/20 I think this should be renamed "attemptHARDownload" - Dylan
[ERROR] ^
[ERROR] /Users/yimin.yang/Documents/Github/saucerest-java/src/main/java/com/saucelabs/saucerest/SauceREST.java:430: error: no tag name after @
[ERROR] * @// TODO: 27/2/20 I think this should be called "downloadHAR" and attemptHARDownload should be the silent failure method - Dylan
[ERROR] ^
[ERROR]
[ERROR] Command line was: /Library/Java/JavaVirtualMachines/openjdk-14.0.1.jdk/Contents/Home/bin/javadoc @options @packages
[ERROR]
[ERROR] Refer to the generated Javadoc files in '/Users/yimin.yang/Documents/Github/saucerest-java/target/apidocs' dir.
[ERROR]
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Fix is to add/edit Javadoc as shown in the error.

File not found download file

I just tested the last snaphot (1.0.38-SNAPSHOT) but
downloadHAR("31631287702d4e418624f8a58cd24397", "/var/tmp/HAR.log");
->
java.io.FileNotFoundException: https://saucelabs.com/rest/v1/rlouvet/jobs/31631287702d4e418624f8a58cd24397/assets/network.har
while extended debug capabilities is enable and visible with saucelabs website

same problem with downloadLog (1.0.37)

here my Job Info: {"browser_short_version": "60", "video_url": "https://saucelabs.com/jobs/31631287702d4e418624f8a58cd24397/video.flv", "creation_time": 1526544496, "custom-data": null, "browser_version": "60.0.3112.78", "owner": "rlouvet", "automation_backend": "webdriver", "id": "31631287702d4e418624f8a58cd24397", "collects_automator_log": false, "record_screenshots": true, "record_video": true, "build": "build-null", "passed": true, "public": "team", "assigned_tunnel_id": null, "status": "in progress", "log_url": "https://saucelabs.com/jobs/31631287702d4e418624f8a58cd24397/selenium-server.log", "start_time": 1526544497, "proxied": false, "modification_time": 1526544525, "tags": ["Tag1"], "name": null, "commands_not_successful": 0, "video_secret": "a2322b77d8ec47618776f748e6fd0294", "consolidated_status": "passed", "selenium_version": null, "manual": false, "end_time": null, "error": null, "os": "Windows 10", "breakpointed": null, "browser": "googlechrome"}

Replace travis-ci with GitHub actions

Is your feature request related to a problem? Please describe.
travis-ci.org is sunset and travis-ci.com is the new platform everyone should migrate to.

Describe the solution you'd like
GitHub actions is what this repo is using for CI as it is more convenient and does not require any migration effort and for the size and purpose of this repo should be more than enough.

Describe alternatives you've considered
Migrating to travis-ci.com but this would require changes on the Sauce Labs account level possibly affecting all other repos. Migrating public repos is also still beta on travis-ci.com

Additional context
None.

Intermittent error on updateJobInfo

I get this error intermittently using SauceRest 1.0.22

Sep 18, 2014 9:09:47 PM com.saucelabs.saucerest.SauceREST updateJobInfo
WARNING: Error closing result stream
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:884)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1323)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.saucelabs.saucerest.SauceREST.updateJobInfo(SauceREST.java:227)

Cookie warnings

WARNING: Invalid cookie header: "Set-Cookie: csrf_token=7b22c57f689f307b96fc0827e5656e9b; expires="Sat, 29-Mar-2014 01:54:11 GMT"; Max-Age=600; Path=/". Unable to parse expires attribute: "Sat, 29-Mar-2014 01:54:11 GMT"

I keep seeing this when using saucerest-java. There's probably some way for the cookie policy to be adjusted so the warning isn't triggered. I ended up disabling logging for the appium training.

LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");

Refactor deleteTunnel() to return the actual response and add unit tests

Description

Currently deleteTunnel() does not handle or returns the response from the server. Basically not telling the user why a call to delete a tunnel has failed.

Motivation and Context

It is implemented differently compared to most other requests. It lacks unit tests as it is not testable with no response returned. If it fails no useful info to the user.

Further comments

Add retries to asset fetching

Assets aren't available immediately after closing a test session. Sauce Labs requires time to process and store assets, and until this process is complete, attempting to fetch an asset will raise a 404.

The library should have configurable retries for asset fetching which avoids this.

Retries should occur at progressively longer periods until the retry count or timeout has been hit. It should then raise an error.

Retries should also be able to be over-ridden for individual requests. For instance, having video ready may take longer then having the log ready.

Refactor getPublicJobLink() to use same code as in latest documentation

Description

Currently method

public String getPublicJobLink(String jobId) {
references an invalid documentation link and the code is also different than our code example in the latest documentation https://docs.saucelabs.com/test-results/sharing-test-results/index.html#building-sharable-links
Investigate if code could be refactored to be clearer.

Motivation and Context

Old and unavailable documentation link is not good. Complex code is unnecessary.

Further comments

Adding proxy details for Sauce rest Java

Hi,

I am creating the saucerest client by proving the user name and access key. I would like to pass the proxy details also as part of the sauce rest client. Can you please let me know how to do that?

Please, add more API for Sauce Connect tunnels management

Could you, please, enrich Sauce Connect tunnel management API (that currently represented by single getTunnels() method) by additional methods such as:

  • getTunnel (String id) - to return SauceTunnel object
  • findTunnel(String identifier) to find SauceTunnel object by tunnel Identifier (don't miss with ID)

Fix ignored test testDoJSONPOST_NotAuthorized() and outputting expected stacktraces

This test is ignored because it is missing some mocking.

    @Ignore("This test didn't run before - was implicitly ignored. Requires fixing.")
    @Test(expected = SauceException.NotAuthorized.class)
    public void testDoJSONPOST_NotAuthorized() throws Exception {
        urlConnection.setResponseCode(401);

        thrown.expect(SauceException.NotAuthorized.class);
        this.sauceREST.doJSONPOST(new URL("http://example.org/blah"), new JSONObject());
    }

Upon running the tests 2 expected IOException gets thrown as part of the test mocking.

java.io.IOException: Expected IO Exception
at com.saucelabs.saucerest.SauceRESTTest$ExceptionThrowingMockInputStream.close(SauceRESTTest.java:62)
at com.saucelabs.saucerest.SauceREST.closeInputStream(SauceREST.java:810)
at com.saucelabs.saucerest.SauceREST.updateJobInfo(SauceREST.java:753)
at com.saucelabs.saucerest.SauceRESTTest.testUpdateJobInfo_NotAuthorized(SauceRESTTest.java:260)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Both things are not ideal and should be fixed to remove clutter and to improve test coverage.

Check whether a job has finished before fetching assets

As per #58, asset fetching can fail if done too soon after a job completes. Because Sauce Labs does asset finalisation during job finalisation, it may be possible to check the job status using the REST API, before attempting to fetch an asset.

This could be part of the retry logic, or its own standalone feature that just raises an exception when assets aren't yet ready.

Create migration guide as a result of #177

Description

As a result of #177 there are breaking changes because deprecated functions are removed. To make it easier for users we should have a migration guide as part of the release and/or in the README.md

Motivation and Context

Avoid confusion and making it easier to change to a new version of saucerest-java.

Further comments

BuildUtils.Java missing

Hi,

When I tried to integrate the SauceRest library into my framework, I am getting error on source SaueRest.java at line number 129, the error is "cannot resolve symbol BuildUtils". I am guessing this is because the BuildUtils class is missing. can you please look into this. Thanks you.

Regards,
-Kalyan.

Exception "Illegal characters" when calling jobFailed()

The test runs (though fails) then an exception is thrown when trying to set the results on he saucelabs job.

Is this related to the code in SauceREST.java? Is there a workaround?

It seems that there is a /r/n tacked on to the "header value: Basic" The log snippet below is literal, except for the starred out chars.

    protected String encodeAuthentication() {
        String auth = username + ":" + accessKey;
        auth = "Basic " + Base64.encodeBase64String(auth.getBytes());
        return auth;
    }

SauceREST info:
com.saucelabs
saucerest
1.0.39

10-23 09:45:37.756 [com.disney.appium.common.BaseTest tearDown] Recording results to saucelabs
10-23 09:45:37.769 [com.disney.appium.common.BaseTest tearDown] Failed to record results to Saucelabs for jobId/sessionId [8dcaac8acc764170af341c508928c14e]
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic cm9iZXJ0YXJsZXN************************************************************

	at sun.net.www.protocol.http.HttpURLConnection.checkMessageHeader(HttpURLConnection.java:541)
	at sun.net.www.protocol.http.HttpURLConnection.isExternalMessageHeaderAllowed(HttpURLConnection.java:492)
	at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3057)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestProperty(HttpsURLConnectionImpl.java:316)
	at com.saucelabs.saucerest.SauceREST.addAuthenticationProperty(SauceREST.java:542)
	at com.saucelabs.saucerest.SauceREST.updateJobInfo(SauceREST.java:562)
	at com.saucelabs.saucerest.SauceREST.jobFailed(SauceREST.java:244)
	at com.disney.appium.common.BaseTest.tearDown(BaseTest.java:203)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
	at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:514)
	at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:215)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:707)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
	at org.testng.TestRunner.privateRun(TestRunner.java:782)
	at org.testng.TestRunner.run(TestRunner.java:632)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
	at org.testng.SuiteRunner.run(SuiteRunner.java:268)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
	at org.testng.TestNG.run(TestNG.java:1064)
	at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:217)
	at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:84)
	at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:92)
	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

adding Junit extension for saucerest ?

I wrote a little extension to saucerest and was just wondering, if it is worth to add it here or if I should host it standalone myself.

I just made a junit TestRule, which calls the "jobFailed" / "jobPasses" methods, automatically after end of teh tests, depedning if it fails or passes.

Just 15 lines of code, but nevertheless reuable.

Regards,

Carsten

Refactor unit tests to follow the same naming convention

Description

Some unit tests do not have a "test" prefix and while this is redundant info (with @Test above) the majority of unit tests do this prefix. As a result it makes sense to just stick with the convention applied to this project.
Other unit tests follow a BDD style of naming. Same as above: refactor so all naming are the same.

Motivation and Context

Different naming conventions in a project causes confusion and it is just ugly.

Further comments

java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter with Java 9

Java 9 ea 181
Saucerest version 1.0.35
Works as expected with the latest version of Java 8
Fails in both command line and within the IntelliJ

Maybe these two websites 1 & 2 might provide some additional information.

Test Case:

public static final String USERNAME = "username";
public static final String ACCESS_KEY = "api_key";
public static final String URL = "https://" + USERNAME + ":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub";
@test
public void testFirefox() throws MalformedURLException {
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "55.0");
WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
driver.get("https://www.google.com/");
System.out.println("title of page is: " + driver.getTitle());
new SauceREST(USERNAME, ACCESS_KEY).jobPassed(((RemoteWebDriver) driver).getSessionId().toString());
driver.quit();
}

Remove silently failing REST calls

Description

Make all REST calls throw exceptions and remove all others who silently fail.

Motivation and Context

This removes really similar code reducing complexity and the need to always provide a silent/non-silent method for every API. In addition, it should be up to the user to decide actively what to do with exceptions thrown as a result of an API call failing. Silently failing can cause issues if the end user does not understand why a test asset was not downloaded. Having exceptions thrown at least promotes actively logging or handling the thrown exception giving more visibility in case of exceptions.

Further comments

In addition this will reduce complexity of the code base.

Feature: add end point for getting the log.json from a job.

Hey, the API is missing a couple methods to get the json formatted logs from a job. I was hoping that you could add the end points so the API can grab them. It's a very minor addition where you just change the appended file on the selenium-server.log -> log.json.

     * Downloads the log file for a Sauce Job and returns it.
     *
     * @param jobId    the Sauce Job Id, typically equal to the Selenium/WebDriver sessionId
     * @return         a BufferedInputStream containing the logfile
     * @throws         IOException if there is a problem fetching the file
     */
    public BufferedInputStream downloadJsonLog(String jobId) throws IOException {
        URL restEndpoint = this.buildURL("v1/" + username + "/jobs/" + jobId + "/assets/log.json");
        return downloadFileData(jobId, restEndpoint);
    }

    /**
     * Downloads the log file for a Sauce Job to the filesystem.  The file will be stored in
     * a directory specified by the <code>location</code> field.
     *
     * @param jobId    the Sauce Job Id, typically equal to the Selenium/WebDriver sessionId
     * @param location represents the base directory where the video should be downloaded to
     */
    public void downloadJsonLog(String jobId, String location) {
        URL restEndpoint = this.buildURL("v1/" + username + "/jobs/" + jobId + "/assets/log.json");
        saveFile(jobId, location, restEndpoint);
    }```

Remove all deprecated functions and their tests

Description

As prep work for version 1.1.0 we will remove old deprecated functions and all related unused code as a result of it. This includes tests.

Motivation and Context

Reduce complexity and code that will be removed sooner or later anyway. Gives us a cleaner state to work on 1.1.0.

Further comments

Use ISO 8601 datetime format for comments and Javadoc to unify used format and make it unambiguous

Definition of ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601)

YYYY-MM-DD or YYYYMMDD
YYYY-MM-DDThh:mm:ssZ

Example
Date

  • 2020-10-05

Date and time in UTC

  • 2020-10-05T15:49:24+00:00
  • 2020-10-05T15:49:24Z
  • 20201005T154924Z

Reason for change
Developers from all over the world might be working and using this library. As a result a datetime format standard should be in place for documentation and comments to avoid confusion. To solve this we should ISO 8601 as a standard.

Create an executable allowing for simple manipulation from the commandline

Sometimes users need to do a one-off manipulation of a job or asset. Spinning up an entire project for this is overkill.

Creating a script that calls the JAR with arguments would give users an easy tool to do things like:

  • Check a job status
  • Update a job status
  • Stop a tunnel
  • Check the contents of Sauce Storage
  • Upload a file to Sauce Storage

job links always pointing to US datacenter

Hi, we using SauceREST and use SauceREST.getPublicJobLink() printing out the job links of failing tests.

As we are now switching to the EU datacenter, we get wrong job links to non existing jobs in the US datacenter.

Is SauceREST using deprecated `/rest/v1/{username}/builds` endpoint?

Is SauceREST using deprecated /rest/v1/{username}/builds endpoint?

I am calling SauceRest.getBuild(String build), parsing out the id, and appending it to https://app.saucelabs.com/vdc/builds/, and finally posting it to our slack channel.

This stopped working a while back and I've finally had time to investigate.

If I'm reading correctly, SauceREST is using v1 endpoints:
https://github.com/saucelabs/saucerest-java/blob/master/src/main/java/com/saucelabs/saucerest/SauceREST.java#L147

And calling the "Get Builds" endpoint here:
https://github.com/saucelabs/saucerest-java/blob/master/src/main/java/com/saucelabs/saucerest/SauceREST.java#L1728-L1731

But that endpoint appears deprecated:
https://docs.saucelabs.com/dev/api/jobs/#builds-methods

DEPRECATED
Builds are now available to both RDC and VDC jobs. Please see the new Builds API for endpoints that incorporate this enhancement.

And when I try to debug using those new v2 endpoints I get subtly different payloads for the same String build, but I can append those v2-derived ids to https://app.saucelabs.com/builds/ and they now work.

I get this payload from SauceRest:

{
    "name": "iAmJacksBuildName",
    "id": "foo",
    "owner": "redact",
    "status": "running",
    "jobs": {
        "completed": 0,
        "finished": 1,
        "queued": 0,
        "failed": 0,
        "running": 1,
        "passed": 1,
        "errored": 0,
        "public": 0
      },
    "creation_time": "redact",
    "start_time": "redact",
    "modification_time": "redact",
    "deletion_time": null,
    "end_time": "redact",
    "group_id": "redact",
    "team_id": "redact",
    "org_id": "redact",
    "passed": null,
    "public": false,
    "run": 0,
    "number": null,
    "prefix": null
  }

and I get this payload from an array in from v2 builds endpoint

{
    "name": "iAmJacksBuildName",
    "id": "bar",
    "owner_id": "redact",
    "status": "success",
    "jobs": {
      "completed": 0,
      "errored": 0,
      "failed": 0,
      "finished": 2,
      "passed": 2,
      "public": 0,
      "queued": 0,
      "running": 0
    },
    "creation_time": "redact",
    "start_time": "redact",
    "modification_time": "redact",
    "deletion_time": null,
    "end_time": "redact",
    "group_id": "redact",
    "team_id": "redact",
    "org_id": "redact",
    "passed": null,
    "public": false,
    "run": 0
  }

Cheers 🍻

Exceptions encountered when fetching assets are effectively invisible.

The downloadLog, downloadVideo and downloadHAR methods all return void. They also have a try/catch block which swallows IOException.

This makes the only way to find out if a file was fetched correctly:

  • To use the methods which only retrieve data, and save it yourself
  • To check the file is created (problematic, see #2)
  • To write to a log and then parse it back (gross)

These methods should throw IOException. Users can deal with this themselves.

Issues while integrating with Selenium

Hi,

I want to integrate saucerest-java with my selenium java project to upload the mobile app binaries to Sauce temp storage, which works great but my test fail with following stack trace. I suspect this is happening because of mismatch in version of common-codec that is used in commons-httpclient 3.1 and RemoteWebDriver (selenium project).

Could you please suggest a workaround? or any guidance how this can be fixed? I tried to change the version on commons-httpclient in pom of saucerest-java to match the version used in Selenium project, but doesn't help.

We want to extend our Sauce usage and this module has a great stuff which will help us in future.

Thanks,
Unmesh

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.agilemd.automation 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ com.agilemd.automation ---
[debug] execute contextualize
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ com.agilemd.automation ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ com.agilemd.automation ---
[debug] execute contextualize
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 12 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ com.agilemd.automation ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.14.1:test (default-test) @ com.agilemd.automation ---
[INFO] Surefire report directory: C:\Users\Admin\Documents\agile_automation\agilemd-automation\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
Uploading C:/Users/Admin/Documents/agile_automation/agilemd-automation/target/test-classes/mobileapps/AgileMD.zip to Sauce Temparaory storage...
File uploaded on Sauce return MD5 d0d478db16ffed3c2a576c0f1c28602d
/C:/Users/Admin/Documents/agile_automation/agilemd-automation/target/test-classes/properties/log4j.properties
/C:/Users/Admin/Documents/agile_automation/agilemd-automation/target/test-classes/properties/log4j.properties
2013-12-28 18:07:58 INFO  TestMonitor:36 - Test Check Search Starts
Config >> SAUCE_IE9_WIN7
2013-12-28 18:07:58 INFO  TestMonitor:36 - Test Check elements on Login Page Starts
Config >> SAUCE_IE9_WIN7
2013-12-28 18:07:58 INFO  Driver:41 - Creating Driver Instance...
2013-12-28 18:07:58 INFO  Driver:42 - Using sauce as mode
2013-12-28 18:07:58 INFO  Driver:41 - Creating Driver Instance...
2013-12-28 18:07:58 INFO  Driver:42 - Using sauce as mode
2013-12-28 18:07:58 INFO  Driver:46 - Using http://xxxx:[email protected]:80/wd/hub as hub
2013-12-28 18:07:58 INFO  Driver:46 - Using http://xxxx:[email protected]:80/wd/hub as hub
2013-12-28 18:07:58 INFO  Driver:64 - Provisioning IE instance
2013-12-28 18:07:58 INFO  Driver:64 - Provisioning IE instance
2013-12-28 18:07:59 INFO  TestMonitor:93 - Test Method testAllElementsOnLoginPage executing...
2013-12-28 18:07:59 INFO  TestMonitor:88 - Test skipped
2013-12-28 18:07:59 INFO  TestMonitor:93 - Test Method testSearchWithPageObject executing...
2013-12-28 18:07:59 INFO  TestMonitor:88 - Test skipped
2013-12-28 18:07:59 INFO  TestMonitor:93 - Test Method testSearchWithPageObject executing...
2013-12-28 18:07:59 INFO  TestMonitor:28 - Test Check elements on Login Page Ends
2013-12-28 18:07:59 INFO  TestMonitor:29 - ---------------------------------------------------------
2013-12-28 18:07:59 INFO  TestMonitor:88 - Test skipped
/C:/Users/Admin/Documents/agile_automation/agilemd-automation/target/test-classes/properties/log4j.properties
2013-12-28 18:07:59 INFO  TestMonitor:28 - Test Check Search Ends
2013-12-28 18:07:59 INFO  TestMonitor:29 - ---------------------------------------------------------
2013-12-28 18:07:59 INFO  TestMonitor:36 - Test Andorid Demo Test Starts
Config >> SAUCE_APPIUM_ANDROID_JELLYBEAN
2013-12-28 18:07:59 INFO  Driver:41 - Creating Driver Instance...
2013-12-28 18:07:59 INFO  Driver:42 - Using sauce as mode
2013-12-28 18:07:59 INFO  Driver:46 - Using http://xxxx:[email protected]:80/wd/hub as hub
2013-12-28 18:08:00 INFO  TestMonitor:93 - Test Method testAndroidMobileLogin executing...
2013-12-28 18:08:00 INFO  TestMonitor:88 - Test skipped
2013-12-28 18:08:00 INFO  TestMonitor:28 - Test Andorid Demo Test Ends
2013-12-28 18:08:00 INFO  TestMonitor:29 - ---------------------------------------------------------
Tests run: 10, Failures: 6, Errors: 0, Skipped: 4, Time elapsed: 378.476 sec <<< FAILURE!
setUp(com.agilemd.automation.uitest.web.SelfCheckingLoginPage)  Time elapsed: 377.728 sec  <<< FAILURE!
java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.<init>(I)V
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:65)
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:84)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
    at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:319)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:298)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at com.softshop.selenium.core.Driver.get(Driver.java:102)
    at com.softshop.selenium.core.BaseTest.setUp(BaseTest.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

setUp(com.agilemd.automation.uitest.web.SearchSmokeTest)  Time elapsed: 377.729 sec  <<< FAILURE!
java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.<init>(I)V
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:65)
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:84)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
    at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:319)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:298)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at com.softshop.selenium.core.Driver.get(Driver.java:102)
    at com.softshop.selenium.core.BaseTest.setUp(BaseTest.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

closeBrowser(com.agilemd.automation.uitest.web.SelfCheckingLoginPage)  Time elapsed: 0.003 sec  <<< FAILURE!
java.lang.NullPointerException: null
    at com.softshop.selenium.core.BaseTest.closeBrowser(BaseTest.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:225)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:114)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

closeBrowser(com.agilemd.automation.uitest.web.SearchSmokeTest)  Time elapsed: 0.01 sec  <<< FAILURE!
java.lang.NullPointerException: null
    at com.softshop.selenium.core.BaseTest.closeBrowser(BaseTest.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:225)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:114)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

setUp(com.agilemd.automation.uitest.android.AndroidLoginTest)  Time elapsed: 0.452 sec  <<< FAILURE!
java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.<init>(I)V
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:65)
    at org.apache.http.impl.auth.BasicScheme.<init>(BasicScheme.java:84)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
    at org.openqa.selenium.remote.HttpCommandExecutor.fallBackExecute(HttpCommandExecutor.java:319)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:298)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:527)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at com.softshop.selenium.core.SwipeableWebDriver.<init>(SwipeableWebDriver.java:14)
    at com.softshop.selenium.core.Driver.get(Driver.java:98)
    at com.softshop.selenium.core.BaseTest.setUp(BaseTest.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

closeBrowser(com.agilemd.automation.uitest.android.AndroidLoginTest)  Time elapsed: 0 sec  <<< FAILURE!
java.lang.NullPointerException: null
    at com.softshop.selenium.core.BaseTest.closeBrowser(BaseTest.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:225)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:114)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:37)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)


Results :

Failed tests: 
  SelfCheckingLoginPage>BaseTest.setUp:62 » NoSuchMethod org.apache.commons.code...
  SearchSmokeTest>BaseTest.setUp:62 » NoSuchMethod org.apache.commons.codec.bina...
  SelfCheckingLoginPage>BaseTest.closeBrowser:76 » NullPointer
  SearchSmokeTest>BaseTest.closeBrowser:76 » NullPointer
  AndroidLoginTest>BaseTest.setUp:62 » NoSuchMethod org.apache.commons.codec.bin...
  AndroidLoginTest>BaseTest.closeBrowser:76 » NullPointer

Tests run: 10, Failures: 6, Errors: 0, Skipped: 4

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6:21.036s
[INFO] Finished at: Sat Dec 28 18:08:00 IST 2013
[INFO] Final Memory: 5M/15M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.14.1:test (default-test) on project com.agilemd.automation: There are test failures.
[ERROR] 
[ERROR] Please refer to C:\Users\Admin\Documents\agile_automation\agilemd-automation\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Replace hardcoded HTTP method string to use pre-defined ENUM

Is your feature request related to a problem? Please describe.
Currently most/all methods use a string for the HTTP method (GET, POST, ...). This should be avoided and refactored to use an ENUM.

Describe the solution you'd like
Replace string HTTP method to use ENUM defined in the JDK.

Describe alternatives you've considered
Create own ENUM and maintain within the project.

Additional context
Add any other context or screenshots about the feature request here.

method stopJob not working, every call is Exception thrown

I call this method this way:
String jobID = ((RemoteWebDriver) this.driver).getSessionId().toString();
SauceREST client = new SauceREST("myacc",",myaccesskey");

    //this works ok
     String jobInfo = client.getJobInfo(jobID);
     System.out.println("Job info: " + jobInfo);
    //here i get exception
     client.stopJob(jobID);

Exception info:
Job info: {"browser_short_version": "32", "video_url": "http://saucelabs.com/jobs/xxxxxxxxxxxxxxxx/video.flv", "creation_time": 1395174814, "custom-data": null, "browser_version": "32.0.1700.107.", "owner": "zzzzzzzzzzzzzz", "id": "xxxxxxxxxxxxxxxxxxxxx", "log_url": "http://saucelabs.com/jobs/4xxxxxxxxxxxxxxxxxxxxxxx/selenium-server.log", "build": null, "passed": null, "public": null, "status": "in progress", "tags": [], "start_time": 1395174815, "proxied": false, "commands_not_successful": 0, "video_secret": "e11ac59e139b4f7db51c4353e6a6132e", "name": "TestSuite, ktery overi funkcnost zakladnich prvku CMS.", "manual": false, "end_time": null, "error": null, "os": "Windows 2008", "breakpointed": null, "browser": "googlechrome"}
III 18, 2014 9:34:14 ODP. com.saucelabs.saucerest.SauceREST stopJob
WARNING: Error updating Sauce Results
java.io.IOException: Server returned HTTP response code: 411 for URL: https://saucelabs.com/rest/v1/xxxxxx/jobs/xxxxxxxxxxxxxxxxxxxxxxxxxxxx
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.saucelabs.saucerest.SauceREST.stopJob(SauceREST.java:230)
at wtests.logic.RunTestNewThread.run(RunTestNewThread.java:180)

III 18, 2014 9:34:14 ODP. com.saucelabs.saucerest.SauceREST stopJob
WARNING: Error closing result stream
java.io.IOException: Server returned HTTP response code: 411 for URL: https://saucelabs.com/rest/v1/xxxxxxxxx/jobs/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1674)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1672)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1670)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1243)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.saucelabs.saucerest.SauceREST.stopJob(SauceREST.java:241)
at wtests.logic.RunTestNewThread.run(RunTestNewThread.java:180)
Caused by: java.io.IOException: Server returned HTTP response code: 411 for URL: https://saucelabs.com/rest/v1/zzzzzzzzzzzzzzzzzzzzzzzzzzzz/jobs/xxxxxxxxxxxxxxxxxxxxxxxxxxx
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.saucelabs.saucerest.SauceREST.stopJob(SauceREST.java:230)
... 1 more

Rename `downloadX` methods so failures are only silent if desired

The current asset fetching methods, downloadVideo, downloadLog and downloadHAR, fail silently.

There are non-silent failure methods which end in orThrow, but I think this is the wrong paradigm. Raising an exception should be the default; users should have to either handle exceptions or explicitly choose a method which makes it clear that failures are silent.

To avoid user confusion, we should consider renaming the methods entirely.

I suggest we:

  1. Deprecate both the downloadXorThrow methods and the downloadX methods
  2. Introduce fetchX and attemptToFetchX methods to replace them, with fetchX throwing exceptions
  3. Wait for the turning of the stars and the dawn of a new era. Or a major release.
  4. Remove the downloadX and orThrow methods.
  5. Rejoice.

I'm not 100% sold on the method names; @diemol and @christian-bromann any thoughts? I wanted something that feels less clunky than 'DownloadOrFailSilently'.

Long Account Names with Sauce REST cause illegal character in message header exception

When using basic authentication, it's possible to trigger something similar to this defect:

http://bugs.sun.com/view_bug.do?bug_id=6459815

Namely, JAVA.LANG.ILLEGALARGUMENTEXCEPTION: ILLEGAL CHARACTER(S) IN MESSAGE HEADER VALUE.

This can be triggered by having an account username of 20+ characters (e.g. 'Kxxxxxxxx_Automation'), combined with the standard length access key, resulting in a 76 character basic authentication encoding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.