Implementasi proses mengunggah file dari wadah dengan browser ke kerangka uji

Otomatisasi Pengujian Akhir-2-Akhir dari sistem informasi terintegrasi
Bagian 2-2. Menerapkan proses mengunggah file dari wadah dengan browser ke kerangka uji. Cari nama file yang diunduh oleh browser


Penulis: habr.com/en/users/anrad
Hubs:
Tags: #autotest, #selenium, #selenoid, #headlessbrowser, #download


Saat kami mengembangkan autotest End-2-End untuk UI, kami dihadapkan dengan pertanyaan "Bagaimana cara mendapatkan nama yang terakhir dimuat file browser dari WebDriver? ", Google tidak mendapatkan apa-apa dengan cepat. Oleh karena itu, saya menulis artikel ini, yang pada saat yang sama memberi tahu apa sebenarnya yang kami punya masalah dan bagaimana kami menyelesaikannya.

Dengan artikel ini, kami melanjutkan serangkaian publikasi tentang bagaimana kami mengotomatiskan proses pengujian manual (selanjutnya disebut sebagai tes otomatis) dari sistem informasi besar (selanjutnya disebut sebagai Sistem) di salah satu proyek LANIT utama dan apa yang datang darinya.

gambar
sumber


Artikel itu sendiri menyelesaikan siklus, di bawah ini adalah tautan ke semua bagian sebelumnya:
Bagian 1. Organisasi dan manajerial. Kenapa kita perlu otomatisasi. Organisasi proses pengembangan dan manajemen. Organisasi penggunaan
Bagian 2. Teknis. Arsitektur dan tumpukan teknis. Detail Implementasi dan Kejutan Teknis
Bagian 2-1. Implementasi kelas dasar untuk semua tes dan JUnit RuleChain,

itu setahun yang lalu. Jadi hari ini mungkin tidak relevan. Tulis di komentar jika Anda tahu cara efisien untuk memproses file dengan beberapa server kotak selenoid.

Ketika mengembangkan "autotests", kami memiliki tugas untuk mengunduh (mengunduh) file dari sistem dengan analisis selanjutnya dari isinya. Untuk "mengunggah" file dari sistem yang diuji, kami menggunakan solusi berikut:
  • untuk mode peluncuran "lokal" (langsung diluncurkan pada PC yang berfungsi) - ketika browser "lokal" diinisialisasi, nama folder lokal sementara dilewatkan sebagai parameter. Selanjutnya, file dibaca langsung dari folder lokal untuk analisis selanjutnya;
  • untuk mode "jarak jauh" (via Bamboo) - file "diambil" dari wadah dengan browser melalui fitur server Solenoid: selenoid-host.example.com : 4444 / unduh / {SESSION_ID} / {FILE_NAME}


Detailnya dijelaskan dalam dokumentasi.

Untuk kedua mode, untuk mengakses file, Anda harus tahu namanya. Ini mengejutkan. Masalah kurangnya data pada nama file "unduh" adalah sebagai berikut:
  • setelah "mengklik" tombol "unduh file", browser mengunduh file ke folder lokal yang sesuai dalam wadah;
  • dalam hal ini, nama file dibentuk secara dinamis dan, bagaimana menentukannya terlebih dahulu, kami tidak dapat menemukannya. Ini adalah fitur dari sistem pengujian kami;
  • Selanjutnya, file ini harus "ditarik keluar" dari wadah dan verifikasi bisnis dari isinya harus dilakukan;
  • untuk "menarik keluar" file, Anda harus tahu namanya, tetapi kami tidak tahu nama itu, karena nama itu dihasilkan secara dinamis dan tidak ada nilai di tautan.


Selain itu, situasi ini diperparah oleh kenyataan bahwa, karena kerumitan besar beberapa tes, beberapa file dapat dibongkar selama tes sebagai bagian dari skrip tes independen yang berbeda dari komposisi tes itu sendiri.
Solusi terbaik bagi kami adalah metode untuk menentukan file yang terakhir diunduh. Ada beberapa cara untuk melakukan ini:
  • . . , ;
  • Google Chrome javascript chrome://downloads/, html-. .




Menganalisis komposisi file yang dimuat browser untuk mode lokal adalah tugas yang sepele.
Untuk mode jarak jauh, Anda perlu menggunakan fitur "tidak berdokumen" dari server selenoid: selenoid-host.example.com : 4444 / unduh / {SESSION_ID} menampilkan daftar semua file yang berhasil diunduh, di mana SESSION_ID adalah ID sesi selenoid
Secara umum, skema bekerja dengan satu pengecualian: kami Anda perlu menunggu beberapa saat hingga file diunduh dan muncul di daftar. Penantian dapat diatur melalui siklus batas waktu, namun demikian, dengan cara ini kami tidak dapat memperoleh informasi tentang kemungkinan kesalahan pengunggahan file. Kami hanya dapat menentukan bahwa file tidak dimuat di sirkuit ini. Oleh karena itu, pada akhirnya, kami menentukan metode untuk menentukan nama file melalui chrome: // Downloads / page.

Mendapatkan nama file melalui chrome: // unduhan / halaman


Metode ini berfungsi sama baiknya dalam mode lokal dan jarak jauh. Skema kerjanya cukup sederhana:
  • jalankan skrip java untuk membuka jendela chrome: // unduhan /;
  • memproses data di jendela dengan cara biasa. Tunggu hingga file pertama dalam daftar dimuat dan tentukan namanya;
  • tutup krom: // unduhan / jendela dan kembalikan nama file yang Anda cari.


Kami googled gagasan menggunakan chrome: // unduhan / dan, sayangnya, saya tidak bisa memberikan tautan ke sumbernya, karena itu belum terpelihara norak. Implementasi aktual kelas untuk mendapatkan nama file diberikan di bawah ini.

Kelas untuk mendapatkan nama file yang diunduh melalui chrome: // unduhan /
	private static final long DOWNLOADS_PAGE_LOAD_TIMEOUT = 5_000;
	private static final long MAX_GET_FILE_NAME_ATTEMPT = 5;
 
	public static String getLastDownloadedFilename() throws DownloaderException {
        String[] filename = new String[1];
        Exception[] ex = new Exception[1];
        WebDriver driver = WebDriverRunner.getWebDriver();
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        Utils.driver.openNewTabCheckAndClose(
                () -> {
                    executor.executeScript("window.open('','_blank');");
                },
                () -> {
                    driver.get("chrome://downloads/");
 
                    for (int i = 0; i < MAX_GET_FILE_NAME_ATTEMPT; i++) {
                    	ex[0] = null;
                        sleep();
                    	try {
                        	WebElement element = (WebElement) executor.executeScript(
                                    "return document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('file-link')");
                        	filename[0] = element.getText();
                            LOGGER.info("Attempt get file name " + i + ". Name = '" + filename[0] + "'");
                    	} catch (WebDriverException e) {
                        	ex[0] = e;
                            LOGGER.info("Failed attempt "+ i + " to get filename text: " + e.getMessage());
                        	continue;
                    	}
                    	if (filename[0] != null && !filename[0].isEmpty()) {
                        	 //             
                         	executor.executeScript(
                                    "document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('remove').click()");
                        	break;
                    	}
                    }
                }
    	);
 
    	if (filename[0] != null && !filename[0].isEmpty()) {
            return filename[0];
    	}
 
    	String message = "Timeout. Can not get last downloaded file name from chrome://downloads/. File name is '" + filename[0] + "'. Exception: " + ex[0].getMessage();
        LOGGER.warning(message);
    	throw new DownloaderException(message, ex[0]);
	}

All Articles