Frameworks
Pick your tool
Selenium is where we started. Selenide, Playwright, WebdriverIO and Vibium are here too, and mobile frameworks are on the way.
Web runs in CI on Linux, Windows and macOS, and some tips on Sauce Labs
Mobile will run on real devices in Sauce Labs
One use case, many tools
How To Upload a File
Every tip solves one use case. Switch the tool to compare how each framework does it.
- Same use case, same test site
- Each example is a full project you can run
- Pick your language inside each tool
- Selenium
- Selenide
- Playwright
- WebdriverIO
- Vibium
- Python
- C#
- Java
- JavaScript
- Ruby
1-upload-a-file/code/python/upload.py
import os
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
@pytest.fixture
def driver_setup_teardown():
driver = webdriver.Firefox()
yield driver
driver.quit()
def test_file_upload(driver_setup_teardown):
driver = driver_setup_teardown
filename = 'some-file.txt'
file = os.path.join(os.getcwd(), filename)
driver.get('https://the-internet.herokuapp.com/upload')
driver.find_element(By.ID, 'file-upload').send_keys(file)
driver.find_element(By.ID, 'file-submit').click()
uploaded_file = driver.find_element(By.ID, 'uploaded-files').text
assert uploaded_file == filename, "uploaded file should be %s" % filename
1-upload-a-file/code/csharp/FileUploadTest.cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace csharp
{
[TestClass]
public class FileUploadTest
{
IWebDriver _driver;
[TestInitialize]
public void SetUp()
{
_driver = new FirefoxDriver();
}
[TestCleanup]
public void TearDown()
{
_driver?.Quit();
}
[TestMethod]
public void UploadFileFromDisk()
{
string File = "SomeFile.txt";
_driver.Url = "https://the-internet.herokuapp.com/upload";
string baseDirectory = AppContext.BaseDirectory;
string relativePath = "../../../SomeFile.txt";
string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));
_driver.FindElement(By.Id("file-upload")).SendKeys(uploadFile);
_driver.FindElement(By.Id("file-submit")).Click();
IWebElement fileName = _driver.FindElement(By.Id("uploaded-files"));
Assert.AreEqual(File, fileName.Text);
}
}
}
1-upload-a-file/code/java/src/test/java/com/elemental/selenium/UploadTest.java
package com.elemental.selenium;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.io.File;
public class UploadTest {
WebDriver driver;
@BeforeEach
public void beforeEach() {
driver = new FirefoxDriver();
}
@AfterEach
public void afterEach() {
if (driver != null) {
driver.quit();
}
}
@Test
public void uploadFile() throws Exception {
String fileName = "some-file.txt";
File file = new File(fileName);
String path = file.getAbsolutePath();
driver.get("https://the-internet.herokuapp.com/upload");
driver.findElement(By.id("file-upload")).sendKeys(path);
driver.findElement(By.id("file-submit")).click();
String text = driver.findElement(By.id("uploaded-files")).getText();
Assertions.assertEquals(fileName, text);
}
}
1-upload-a-file/code/javascript/test/upload.spec.js
const assert = require("assert");
const {Builder, By} = require("selenium-webdriver");
const path = require("path");
describe("Upload Test", function () {
let driver;
beforeEach(async function () {
driver = await new Builder().forBrowser("firefox").build();
});
afterEach(async function () {
await driver.quit();
});
it("upload a file", async function () {
let filename = "some-file.txt";
let filePath = path.join(process.cwd(), filename);
await driver.get("https://the-internet.herokuapp.com/upload");
await driver.findElement(By.id("file-upload")).sendKeys(filePath);
await driver.findElement(By.id("file-submit")).click();
let text = await driver.findElement(By.id("uploaded-files")).getText();
assert.equal(text, filename);
});
});
1-upload-a-file/code/ruby/upload.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
def setup
@driver = Selenium::WebDriver.for(:firefox)
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
filename = 'some-file.txt'
file = File.join(Dir.pwd, filename).tr('/', File::ALT_SEPARATOR || '/')
@driver.get('https://the-internet.herokuapp.com/upload')
@driver.find_element(id: 'file-upload').send_keys(file)
@driver.find_element(id: 'file-submit').click
uploaded_filename = @driver.find_element(id: 'uploaded-files').text
expect(uploaded_filename).to eq(filename)
end
- Java
1-upload-a-file/code/selenide/src/test/java/com/elemental/selenium/UploadTest.java
package com.elemental.selenium;
import static com.codeborne.selenide.Condition.text;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.open;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
public class UploadTest {
@BeforeEach
void openAUT() {
open("https://the-internet.herokuapp.com/upload");
}
@Test
public void uploadFile() {
$("#file-upload").uploadFromClasspath("selenide-intro.txt");
$("#file-submit").click();
$("#uploaded-files").shouldHave(text("selenide-intro.txt"));
}
@Test
public void uploadFileUsingPath() {
$("#file-upload").uploadFile(new File("src/test/resources/selenide-intro.txt"));
$("#file-submit").click();
$("#uploaded-files").shouldHave(text("selenide-intro.txt"));
}
}
- TypeScript
- Python
- C#
- Java
1-upload-a-file/code/playwright/tests/upload.spec.ts
import {test, expect} from '@playwright/test';
import path from 'path';
test('upload a file', async ({page}) => {
const filename = 'some-file.txt';
const filePath = path.join(process.cwd(), filename);
await page.goto('https://the-internet.herokuapp.com/upload');
await page.locator('#file-upload').setInputFiles(filePath);
await page.locator('#file-submit').click();
await expect(page.locator('#uploaded-files')).toHaveText(filename);
});
1-upload-a-file/code/playwright-python/upload.py
import os
from playwright.sync_api import Page, expect
def test_file_upload(page: Page):
filename = 'some-file.txt'
file_path = os.path.join(os.getcwd(), filename)
page.goto('https://the-internet.herokuapp.com/upload')
page.locator('#file-upload').set_input_files(file_path)
page.locator('#file-submit').click()
expect(page.locator('#uploaded-files')).to_have_text(filename)
1-upload-a-file/code/playwright-csharp/UploadTest.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Playwright.MSTest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace PlaywrightTests
{
[TestClass]
public class UploadTest : PageTest
{
[TestMethod]
public async Task UploadFile()
{
string filename = "some-file.txt";
string filePath = Path.Combine(AppContext.BaseDirectory, filename);
await Page.GotoAsync("https://the-internet.herokuapp.com/upload");
await Page.Locator("#file-upload").SetInputFilesAsync(filePath);
await Page.Locator("#file-submit").ClickAsync();
await Expect(Page.Locator("#uploaded-files")).ToHaveTextAsync(filename);
}
}
}
1-upload-a-file/code/playwright-java/src/test/java/com/elemental/playwright/UploadTest.java
package com.elemental.playwright;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.junit.UsePlaywright;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
@UsePlaywright
class UploadTest {
@Test
void uploadFile(Page page) {
String filename = "some-file.txt";
Path path = Path.of(filename).toAbsolutePath();
page.navigate("https://the-internet.herokuapp.com/upload");
page.locator("#file-upload").setInputFiles(path);
page.locator("#file-submit").click();
assertThat(page.locator("#uploaded-files")).hasText(filename);
}
}
- TypeScript
1-upload-a-file/code/webdriverio/test/upload.e2e.ts
import {browser, $, expect} from '@wdio/globals';
import path from 'path';
describe('Upload Test', () => {
it('upload a file', async () => {
const filename = 'some-file.txt';
const filePath = path.join(process.cwd(), filename);
await browser.url('https://the-internet.herokuapp.com/upload');
await $('#file-upload').setValue(filePath);
await $('#file-submit').click();
await expect($('#uploaded-files')).toHaveText(filename);
});
});
- JavaScript
- Python
- Java
1-upload-a-file/code/vibium/test/upload.spec.js
const assert = require('assert');
const path = require('path');
const {browser} = require('vibium');
describe('Upload Test', function () {
let bro;
let page;
beforeEach(async function () {
bro = await browser.start();
page = await bro.page();
});
afterEach(async function () {
await bro.stop();
});
it('upload a file', async function () {
const filename = 'some-file.txt';
const filePath = path.join(process.cwd(), filename);
await page.go('https://the-internet.herokuapp.com/upload');
await page.find('#file-upload').setFiles([filePath]);
await page.find('#file-submit').click();
const text = await page.find('#uploaded-files').text();
assert.equal(text, filename);
});
});
1-upload-a-file/code/vibium-python/upload.py
import os
import pytest
from vibium import browser
@pytest.fixture
def page():
bro = browser.start()
yield bro.page()
bro.stop()
def test_file_upload(page):
filename = 'some-file.txt'
file_path = os.path.join(os.getcwd(), filename)
page.go('https://the-internet.herokuapp.com/upload')
page.find('#file-upload').set_files([file_path])
page.find('#file-submit').click()
uploaded_file = page.find('#uploaded-files').text()
assert uploaded_file == filename
1-upload-a-file/code/vibium-java/src/test/java/com/elemental/vibium/UploadTest.java
package com.elemental.vibium;
import com.vibium.Browser;
import com.vibium.Page;
import com.vibium.Vibium;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.List;
public class UploadTest {
Browser browser;
Page page;
@BeforeEach
public void beforeEach() {
browser = Vibium.start();
page = browser.page();
}
@AfterEach
public void afterEach() {
if (browser != null) {
browser.stop();
}
}
@Test
public void uploadFile() {
String fileName = "some-file.txt";
String path = new File(fileName).getAbsolutePath();
page.go("https://the-internet.herokuapp.com/upload");
page.find("#file-upload").setFiles(List.of(path));
page.find("#file-submit").click();
String text = page.find("#uploaded-files").text();
Assertions.assertEquals(fileName, text);
}
}
Tips
Where to begin
Start here
Why trust the code
Tested, not just written
Runs every night
CI runs the web examples on three operating systems. A broken example fails the build.
ubuntuwindowsmacos
Real devices for mobile
Mobile tips need devices and emulators, so they will run in Sauce Labs. You can run them with a free account.
Short and focused
One use case per tip, with a walkthrough of every important line. Read it in five minutes.
Know a better way?
Write a tip, add your language or framework to an existing one, or fix an example. We review every pull request.