How to Upload and Validate files using Selenium for Java Apps!
Published: 2022-07-15 21:34:30


You've probably heard of Selenium WebDriver, the widely popular browser automation library right? Did you know that it has the ability to allow users to simulate a file upload event? If not, keep reading and you'll soon find out how to automate the file upload feature along with how to validate image files and non-image files using Selenium for Java applications!


![Figure 1: Upload a file in Selenium!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ov1r3vh1t1ljg1xrda4x.png)

<i style={{ textAlign: 'center' }}>_Figure 1: Upload a file in Selenium!_</i>

## Setup

For this short tutorial we'll be using the following example Java application hosted on GitHub: [Java Selenium Examples](https://github.com/ShehanAT/java-selenium-examples)

Start by cloning the project and opening it up in Eclipse or Intellij IDEA. I'll be using Eclipse for this tutorial.

Note: If you want to follow along with a different Java application feel free to do so.

### Setting up environmental variables

If you're using Eclipse, make sure to following these steps so that the paths to your local installations of `geekodriver` and `firefox.bin` are set:

1. Navigate to the Run Configurations page via `Run` -> `Run Configurations`
2. Select the `JUnit` configuration that you plan to use in running the tests
3. Navigate to the `Environment` tab
4. Click on `Add` and enter the following key/value pairs:
   - `FIREFOX_PATH`: Your local path to your `firefox` executable file. For example it should look like the following if you're using Windows: `C:\\Program Files\\Mozilla Firefox\\firefox.exe`
   - `GEEKODRIVER_PATH`: Your local path to your `geckodriver` executable file. Here's what a Windows path should look like: `C:\\..\\geckodriver\\geckodriver.exe`
   - `IMAGE_FILE_UPLOAD_PATH`: Your local path to any image file(files with the extention `.png`, `.jpg`, `.jpeg`, `.svg`, etc) that we can use for testing the image file upload functionality detailed further along this tutorial
   - `NON_IMAGE_FILE_UPLOAD_PATH`: Your local path to any non-image files that we can use of testing the non-image file upload functionality detailed further along in this tutorial
   - `IMAGE_FILE_NAME`: The name of the same image file you referenced in the `IMAGE_FILE_UPLOAD_PATH` environment variable. For example: if your `IMAGE_FILE_UPLOAD_PATH` variable is set to `C:\\bob\\image1.png` then `IMAGE_FILE_NAME` should be set to `image1.png`
   - `NON_IMAGE_FILE_NAME`: The name of the same image file you referenced in the `NON_IMAGE_FILE_UPLOAD_PATH` environment variable. For example: if your `NON_IMAGE_FILE_UPLOAD_PATH` variable is set to `C:\\bob\\non-image1.png` then `NON_IMAGE_FILE_NAME` should be set to `non-image1.png`
5. Click `Apply` to save changes

## Testing

Let's navigate to the `src.com.codinginformer.test.SeleniumUploadFile` class and go through its methods, starting with the `@Before` method:

```
	@Before
	public void initFirefox() {
		Properties properties = new Properties();
		System.setProperty("webdriver.gecko.driver", System.getenv("GEEKODRIVER_PATH"));
		System.setProperty("webdriver.firefox.bin", System.getenv("FIREFOX_PATH"));
		WebDriver driver = new FirefoxDriver();
	}
```

The above method establishes properties for `geckodriver`. It needs the local `geckodriver` executable file path set to the `webdriver.gecko.driver` property along with the `firefox` executable file set to wherever your local `firefox` executable file resides
Finally, we instantiate the `FirefoxDriver()` class to the `driver` variable

Next, let's cover the `uploadImageFile()` method:

```
	@Test
	public void uploadImageFile() {
	        String baseUrl = "https://selenium-testing-website.herokuapp.com/upload";

	        WebDriver driver = new FirefoxDriver();

	        driver.get(baseUrl);
	        WebElement uploadElement = driver.findElement(By.id("file-upload"));


	        uploadElement.sendKeys(System.getenv("IMAGE_FILE_UPLOAD_PATH"));


	        driver.findElement(By.id("file-submit")).click();

	    	driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

	    	WebElement javaLogo = driver.findElement(By.xpath("//img[@src='/uploads/" + System.getenv("IMAGE_FILE_NAME") + "']"));

	    	Assert.assertEquals(javaLogo.getAttribute("src"), "https://selenium-testing-website.herokuapp.com/uploads/" + System.getenv("IMAGE_FILE_NAME"));
	}
```

Here is an explanation for the above test:

- `driver.get(baseUrl);`: The `get()` method is used to launch a new browser session to the URL specified. This URL is specifically picked out because it contains a file upload form that we'll use for this tutorial
- `WebElement uploadElement = driver.findElement(By.id("file-upload"));`: The file upload `input` element is identified using its id via `By.id()` and assigned to a `WebElement` class instance(More on Selenium WebElement [in their official docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebElement.html))
- `uploadElement.sendKeys(System.getenv("IMAGE_FILE_UPLOAD_PATH"));`: The `sendkeys()` method is used to type content automatically into editable fields while using Selenium. In this cases, we're passing in a file path of an image contained within our local system so that the specified file can be uploaded as an image
- `driver.findElement(By.id("file-submit")).click();`: Here we're finding the submit button via the `By.id()` method(more on it [in the official docs](https://www.selenium.dev/documentation/webdriver/elements/finders/#evaluating-a-subset-of-the-dom)). Then the `click()` method is used to simulate clicking the submit button in the web form
- `driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);`: Now we tell Selenium to wait for two seconds before continuing the execution. This allows for the next page to load
- `WebElement javaLogo = driver.findElement(By.xpath("//img[@src='/uploads/" + System.getenv("IMAGE_FILE_NAME") + "']"));`: Then we look for the uploaded image in the following page by using `By.xpath()`(more on `By.xpath()` in [this great blog post](https://www.lambdatest.com/blog/complete-guide-for-using-xpath-in-selenium-with-examples/))
- `Assert.assertNotNull(javaLogo);`: Finally we validate that the image we uploaded in the previous screen indeed does appear in the current page. We do this by getting its `src` attribute and comparing it to the image file name we passed in. In order to do this, we have to add the website URL with the string `/uploads/` to the expected value field of the `Assert.assertEquals()` call because the actual outcome value is going to be is that specified format

Ok, let's move on to the next test `uploadNonImageFile()`:

```
	@Test
	public void uploadNonImageFile() {
	        String baseUrl = "https://selenium-testing-website.herokuapp.com/upload";

	        WebDriver driver = new FirefoxDriver();

	        driver.get(baseUrl);
	        WebElement uploadElement = driver.findElement(By.id("file-upload"));


	        uploadElement.sendKeys(System.getenv("NON_IMAGE_FILE_UPLOAD_PATH"));


	        driver.findElement(By.id("file-submit")).click();

	    	driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

	    	WebElement nonImageText = driver.findElement(By.xpath("//*[contains(text(), '/uploads/" + System.getenv("NON_IMAGE_FILE_NAME") + "')]"));

	    	Assert.assertNotNull(nonImageText);
	}
```

Here is an explanation for the above test:

- The purpose of this test is to evaluate whether uploading a non-image file will render the `uploaded_non_image.erb` view file with the non-image file path contained within it.
- The beginning part of this test uses the same structure as the first test
- `uploadElement.sendKeys(System.getenv("NON_IMAGE_FILE_UPLOAD_PATH"));`: This time, we're passing in a file path of a non-image file contained within our local system in order to test the above functionality
- `driver.findElement(By.id("file-submit")).click();`: Here we're finding the submit button via the `By.id()` method(more on it [in the official docs](https://www.selenium.dev/documentation/webdriver/elements/finders/#evaluating-a-subset-of-the-dom)). Then the `click()` method is used to simulate clicking the submit button in the web form
- `driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);`: Now we tell Selenium to wait for two seconds before continuing the execution. This allows for the next page to load
- `WebElement nonImageText = driver.findElement(By.xpath("//*[contains(text(), '/uploads/" + System.getenv("NON_IMAGE_FILE_NAME") + "')]"));`: Then we look for the uploaded file name text in the following page by using `By.xpath()`
- `Assert.assertNotNull(nonImageText);`: Finally we validate that the file name text does indeed appear in the current page using the `Assert.assertNotNul()` method(more on [this method here](https://www.javaguides.net/2018/08/junit-assert.assertnotnull-method-example.html))

Now just right click on the `SeleniumUploadFile.java` file and select `Run As -> JUnit Test` in order to run our test.


![Figure 2: Image Uploaded page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k10k3g6h6rtyaf7ico5m.png)

<i style={{ textAlign: 'center' }}>_Figure 2: Image Uploaded page_</i>


![Figure 3: Non Image Uploaded page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7c6dl74uo8cbmzi5oif.png)

<i style={{ textAlign: 'center' }}>_Figure 3: Non Image Uploaded page_</i>


![Figure 4: Eclipse showing our two passing tests](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8p2vyem38eqpw5421i9.png)

<i style={{ textAlign: 'center' }}>_Figure 4: Eclipse showing our two passing tests_</i>

And with that, we're able to to implement the file upload feature offered by Selenium WebDriver! Also, we've covered how to use `By.id()` and `By.xpath()` to locate `img` elements and elements containing certain texts in a given webpage, thereby killing two birds with one stone!

Congrats if you managed to get this functionality working. If not, leave a comment in the comments section and I'll get back to you if I find the time.

## Conclusion

Thanks for reading this blog post!

If you have any questions or concerns please feel free to post a comment in this post and I will get back to you when I find the time.

If you found this article helpful please share it and make sure to follow me on [Twitter](https://twitter.com/SeanAtukorala) and [GitHub](https://github.com/ShehanAT), connect with me on [LinkedIn](https://www.linkedin.com/in/shehan-atukorala-8631491a5/) and subscribe to my [YouTube channel](https://www.youtube.com/channel/UCtxed_NljgtAXrQMMdLvhrQ).