com.daarons.transfer.UploadTask.java Source code

Java tutorial

Introduction

Here is the source code for com.daarons.transfer.UploadTask.java

Source

/*
 * Copyright 2016 David Aarons.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daarons.transfer;

import com.daarons.controller.TransferSettingsController;
import com.daarons.dao.TransferRecordDAO;
import com.daarons.dao.TransferRecordDAOCsvImpl;
import com.daarons.model.Message;
import com.daarons.model.TransferRecord;
import com.daarons.model.UploadTransferObject;
import com.daarons.springconfig.SpringConfig;
import java.sql.Timestamp;
import javafx.collections.ObservableList;
import org.apache.logging.log4j.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.Iterator;
import javafx.concurrent.Task;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;

/**
 *
 * @author David
 */
public class UploadTask extends Task {

    private static final Logger log = LogManager.getLogger(UploadTask.class);
    private WebDriver driver;
    private WebDriverWait longWait, smallWait;
    private ObservableList<UploadTransferObject> uploadList;
    private TransferRecordDAO dao;

    public UploadTask(ObservableList<UploadTransferObject> uploadList) {
        this.uploadList = uploadList;
        dao = new TransferRecordDAOCsvImpl();
    }

    @Override
    protected Object call() throws Exception {
        initUploadTask();

        acceptToS(); //put before login?

        String emailAddress = getTransferSettingsController().getEmailAddress();
        String password = getTransferSettingsController().getPassword();
        boolean loggedIn = false;
        if (!emailAddress.isEmpty() && !password.isEmpty()) {
            loggedIn = logIn(emailAddress, password);
        }

        Iterator<UploadTransferObject> i = uploadList.iterator();
        while (i.hasNext()) {
            UploadTransferObject uploadTransferObject = i.next();
            clickButtonToChooseEmailOrLink();
            Message message = uploadTransferObject.getMessage();
            boolean sendingEmail = false;
            boolean gettingLink = false;
            if (message != null) {
                clickEmailButton();
                inputMessage(message);
                sendingEmail = true;
            } else {
                clickLinkButton();
                gettingLink = true;
            }

            String uploadPassword = uploadTransferObject.getPassword();
            if (uploadPassword != null && loggedIn) {
                enterUploadPassword(uploadPassword);
            }

            clickButtonToChooseEmailOrLink();

            inputFilePath(uploadTransferObject.getUrl());
            clickTransferButtonWithText("Transfer");

            String downloadLink = null;
            int timeWaited = 0;
            boolean isUploadTimeAvailable = isUploadTimeAvailable(longWait);
            boolean isLinkAvailable = false;
            boolean isEmailSent = false;

            if (!isUploadTimeAvailable) {
                //check if the upload if finished. Maybe it was a small file and uploaded quickly.
                if (sendingEmail) {
                    isEmailSent = isTransferButtonWithTextAvailable("Send another?", longWait);
                } else if (gettingLink) {
                    isLinkAvailable = isLinkAvailable(smallWait);
                }

                //if upload isn't finished
                if (!isEmailSent && !isLinkAvailable) {
                    //look for upload time again
                    isUploadTimeAvailable = isUploadTimeAvailable(longWait);

                    if (!isUploadTimeAvailable) {
                        log.error("Couldn't upload this file. Continuing to next file.");
                        TransferRecord transferRecord = createTransferRecord(uploadTransferObject, "Failed");
                        dao.addTransferRecord(transferRecord);
                        continue;
                    }
                }
            }

            if (isUploadTimeAvailable) {
                int timeUntilUploadFinished = getUploadTime(smallWait);

                //create new webdriverwait based on upload time + some extra time 
                //just in case slow connection 
                WebDriverWait uploadWait = new WebDriverWait(driver, (timeUntilUploadFinished * 60) + (30 * 60));

                if (sendingEmail) {
                    isEmailSent = isTransferButtonWithTextAvailable("Send another?", uploadWait);
                } else if (gettingLink) {
                    isLinkAvailable = isLinkAvailable(uploadWait);
                }

                if (!isEmailSent && !isLinkAvailable) {
                    log.error("The upload time is done, but the web element cannot be found");
                    if (isUploadTimeAvailable(smallWait)) {
                        timeWaited += (timeUntilUploadFinished * 60) + (30 * 60);
                        timeUntilUploadFinished = getUploadTime(smallWait);
                        uploadWait = new WebDriverWait(driver, (timeUntilUploadFinished * 60) + (30 * 60));

                        //calculate time waited if there's a future failure
                        timeWaited += (timeUntilUploadFinished * 60) + (30 * 60);
                        timeWaited /= 60;//time waited in minutes for failure

                        if (sendingEmail) {
                            isEmailSent = isTransferButtonWithTextAvailable("Send another?", uploadWait);
                        } else if (gettingLink) {
                            isLinkAvailable = isLinkAvailable(uploadWait);
                        }

                        if (!isEmailSent && !isLinkAvailable) {
                            log.error("Couldn't upload this file. Continuing to next file.");
                            TransferRecord transferRecord = createTransferRecord(uploadTransferObject, "Failed");
                            dao.addTransferRecord(transferRecord);
                            continue;
                        }

                    } else if (sendingEmail && !isTransferButtonWithTextAvailable("Send another?", smallWait)) {
                        log.error("Couldn't upload this file. Continuing to next file.");
                        TransferRecord transferRecord = createTransferRecord(uploadTransferObject, "Failed");
                        dao.addTransferRecord(transferRecord);
                        continue;
                    } else if (gettingLink && !isLinkAvailable(smallWait)) {
                        log.error("Couldn't upload this file. Continuing to next file.");
                        TransferRecord transferRecord = createTransferRecord(uploadTransferObject, "Failed");
                        dao.addTransferRecord(transferRecord);
                        continue;
                    }
                }
            }

            WebElement linkElement = null;
            if (gettingLink) {
                linkElement = smallWait
                        .until(ExpectedConditions.presenceOfElementLocated(By.className("transfer__textfield")));
                downloadLink = linkElement.getAttribute("value");
            }

            if (sendingEmail) {
                downloadLink = message.getTo().replaceAll(",", " ");
            }

            TransferRecord transferRecord = createTransferRecord(uploadTransferObject, downloadLink);

            dao.addTransferRecord(transferRecord);

            try {
                if (gettingLink) {
                    linkElement.click();
                    clickTransferButtonWithText("Ok");
                } else if (isEmailSent) {
                    clickTransferButtonWithText("Send another?");
                }
                clickTransferButtonWithText("Continue");
                Thread.sleep(5000);
            } catch (Exception ex) {
                log.error("Couldn't click button. Uploading next file.", ex);
            }
        }

        if (loggedIn) {
            logOut();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {
                log.error(ex);
            }
        }

        clearTableView("upload");
        driver.quit();

        return null;
    }

    private TransferRecord createTransferRecord(UploadTransferObject uploadTransferObject, String downloadLink) {
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setTimestamp(new Timestamp(System.currentTimeMillis()));
        transferRecord.setOperation("upload");
        transferRecord.setLocalFile(uploadTransferObject.getUrl());
        transferRecord.setLink(downloadLink);
        return transferRecord;
    }

    private void initUploadTask() {
        initChromeDriver();
        longWait = new WebDriverWait(driver, 60);
        smallWait = new WebDriverWait(driver, 3);
        driver.get("https://wetransfer.com/sign-in");
    }

    private void initChromeDriver() {
        System.setProperty("webdriver.chrome.driver", "chromedriver_win32/chromedriver.exe");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        driver = new ChromeDriver(options);
    }

    private void acceptToS() {
        try {
            clickTransferButtonWithText("I agree");
        } catch (Exception ex) {
            log.error("Couldn't accept ToS", ex);
        }
    }

    private void clickTransferButtonWithText(String text) throws Exception {
        if (isTransferButtonWithTextAvailable(text, longWait)) {
            WebElement transferButton = smallWait
                    .until(ExpectedConditions.presenceOfElementLocated(By.className("transfer__button")));
            transferButton.click();
        } else {
            throw new Exception("Button with text " + text + " does not exist");
        }
    }

    private boolean isTransferButtonWithTextAvailable(String text, WebDriverWait wait) {
        return wait
                .until(ExpectedConditions.textToBePresentInElementLocated(By.className("transfer__button"), text));
    }

    private boolean logIn(String emailAddress, String password) {
        try {
            WebElement emailInput = longWait.until(ExpectedConditions.presenceOfElementLocated(
                    By.cssSelector("#signin__form > div > div > form > div:nth-child(1) > input")));
            emailInput.sendKeys(emailAddress);
            WebElement passwordInput = longWait.until(ExpectedConditions.presenceOfElementLocated(
                    By.cssSelector("#signin__form > div > div > form > div:nth-child(2) > input")));
            passwordInput.sendKeys(password);
            WebElement logInButton = longWait.until(ExpectedConditions
                    .presenceOfElementLocated(By.cssSelector("#signin__form > div > div > form > button")));
            logInButton.click();
            Thread.sleep(5000);
            return true;
        } catch (Exception ex) {
            log.error("Problem", ex);
            return false;
        }
    }

    private void clickButtonToChooseEmailOrLink() {
        WebElement emailOrLinkButton = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.transfer__footer > svg")));
        emailOrLinkButton.click();
    }

    private void clickEmailButton() {
        WebElement emailButton = smallWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer > div > div.scrollable.transfer__contents.scrollable--overflow-top > div.scrollable__content > div.transfer__options > div.transfer__option > div > svg > path")));
        String transform = getTransformAttribute(emailButton);
        if (!transform.equals("translate(0, 0)")) {
            emailButton.click();
        }
    }

    private String getTransformAttribute(WebElement button) {
        String transform = button.getAttribute("transform");
        return transform;
    }

    private void inputMessage(Message message) {
        WebElement toInput = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.scrollable.transfer__contents > div.scrollable__content > div.uploader__fields > div.uploader__autosuggest > input")));
        toInput.clear();
        toInput.sendKeys(message.getTo());
        WebElement fromInput = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.scrollable.transfer__contents > div.scrollable__content > div.uploader__fields > input")));
        fromInput.clear();
        fromInput.sendKeys(message.getFrom());
        WebElement messageInput = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.scrollable.transfer__contents > div.scrollable__content > div.uploader__fields > div.uploader__message > textarea")));
        messageInput.clear();
        messageInput.sendKeys(message.getMessage());
    }

    private void clickLinkButton() {
        WebElement linkButton = smallWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer > div > div.scrollable.transfer__contents.scrollable--overflow-top > div.scrollable__content > div.transfer__options > div.transfer__option > div > svg > path")));
        String transform = getTransformAttribute(linkButton);
        if (transform.equals("translate(0, 0)")) {
            linkButton.click();
        }
    }

    private void enterUploadPassword(String transferPassword) {
        WebElement transferPasswordInput = longWait
                .until(ExpectedConditions.presenceOfElementLocated(By.id("transfer__password")));
        transferPasswordInput.sendKeys(transferPassword);
    }

    private void inputFilePath(String filePath) {
        WebElement fileInput = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.scrollable.transfer__contents > div.scrollable__content > div.uploader__files > form > input[type=\"file\"]")));
        fileInput.sendKeys(filePath);
    }

    private boolean isUploadTimeAvailable(WebDriverWait wait) {
        //checks to see if the time until the upload is finished is on the screen
        boolean isUploadTimeAvailable;
        try {
            isUploadTimeAvailable = wait.until((ExpectedCondition<Boolean>) (WebDriver driver2) -> driver2
                    .findElement(By.cssSelector(
                            "body > div > div > div.transfer.transfer--half-panel > div > div.transfer__contents > p:nth-child(4)"))
                    .getText().length() != 0);
        } catch (org.openqa.selenium.TimeoutException ex) {
            log.error("Time until upload is finished could not be found", ex);
            isUploadTimeAvailable = false; //remove and make false at start of method
        }
        return isUploadTimeAvailable;
    }

    private boolean isOkButtonClickable(WebDriverWait wait) {
        //checks to see if the Ok Button is ready to be clicked meaning upload is finished
        boolean isOkButtonClickable;
        try {
            isOkButtonClickable = wait.until((ExpectedCondition<Boolean>) (WebDriver driver2) -> !driver2
                    .findElement(By.className("transfer__button")).getText().equals("Transfer")
                    && !driver2.findElement(By.className("transfer__button")).getText().equals("Cancel"));
        } catch (Exception ex) {
            log.error(ex);
            isOkButtonClickable = false;
        }
        return isOkButtonClickable;
    }

    private boolean isLinkAvailable(WebDriverWait wait) {
        //checks to see if the download link is ready
        boolean isLinkAvailable;
        try {
            isLinkAvailable = wait.until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(
                    "body > div > div > div.transfer.transfer--half-panel > div > div.transfer__contents > p"),
                    "Copy your download link:"));
        } catch (org.openqa.selenium.TimeoutException ex) {
            log.error("The download link for the file could not be found", ex);
            isLinkAvailable = false;
        }
        return isLinkAvailable;
    }

    private int getUploadTime(WebDriverWait wait) {
        WebElement timeLeftElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > div.transfer.transfer--half-panel > div > div.transfer__contents > p:nth-child(4)")));

        // then get the text in the time_left element & calculate the time to upload
        String timeLeft = timeLeftElement.getText();
        int until;
        if (timeLeft.matches("(.*)hour(.*)") || timeLeft.matches("(.*)hours(.*)")) { //hours
            timeLeft = timeLeft.replaceAll("\\D+", "");
            if (timeLeft.isEmpty()) {
                until = 60;
            } else {
                until = new Integer(timeLeft) * 60;
            }
        } else if (timeLeft.matches("(.*)under a minute(.*)")) { // < 1min
            until = 1;
        } else { //everything else but mostly 'minutes'
            timeLeft = timeLeft.replaceAll("\\D+", "");
            try {
                until = new Integer(timeLeft);
            } catch (NumberFormatException ex) {
                log.error("The upload time did not contains integers", ex);
                until = 1;
            }
        }
        return until;
    }

    private void logOut() {
        WebElement accountLink = longWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(
                "body > div > div > nav > ul > li.nav__item.nav_item--expanded.nav__item--active > ul > li:nth-child(4) > a")));
        accountLink.click();
        WebElement signOutButton = longWait
                .until(ExpectedConditions.presenceOfElementLocated(By.className("account__signout")));
        signOutButton.click();
    }

    private void clearTableView(String table) {
        getTransferSettingsController().clearTable(table);
    }

    private TransferSettingsController getTransferSettingsController() {
        return SpringConfig.getApplicationContext().getBean(TransferSettingsController.class);
    }
}