testsuite/ui/satellite: add browser tests
Also, we have multiple tests that contain the same sign up and login logic and refactoring them would make tests cleaner and more readable. Change-Id: I25bf95ca2fffb7f494a3c93a4a4afe429ece70d3
This commit is contained in:
parent
6dffbd4173
commit
5ed3846e16
@ -364,7 +364,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh 'psql -U postgres -c \'create database testui;\''
|
sh 'psql -U postgres -c \'create database testui;\''
|
||||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||||
sh 'cd testsuite && go test -parallel 1 -p 1 -vet=off -timeout 32m -json -race ./... 2>&1 | tee ../.build/ui-tests.json | xunit -out ../.build/ui-tests.xml'
|
sh 'cd testsuite && go test -parallel 1 -p 1 -short -vet=off -timeout 32m -json -race ./... 2>&1 | tee ../.build/ui-tests.json | xunit -out ../.build/ui-tests.xml'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
|
249
testsuite/ui/satellite/browser_features_test.go
Normal file
249
testsuite/ui/satellite/browser_features_test.go
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
// Copyright (C) 2021 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package satellite_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"storj.io/common/testcontext"
|
||||||
|
"storj.io/storj/testsuite/ui/uitest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBrowserFeatures(t *testing.T) {
|
||||||
|
uitest.Edge(t, func(t *testing.T, ctx *testcontext.Context, planet *uitest.EdgePlanet, browser *rod.Browser) {
|
||||||
|
page := openPage(browser, planet.Satellites[0].ConsoleURL())
|
||||||
|
|
||||||
|
// Sign up and login.
|
||||||
|
signUpWithUser(t, planet, page)
|
||||||
|
loginWithUser(t, planet, page)
|
||||||
|
|
||||||
|
// Navigate into browser with new onboarding.
|
||||||
|
page.MustElementR("a", "Skip and go directly to dashboard").MustClick()
|
||||||
|
page.MustElementR("p", "Objects").MustClick()
|
||||||
|
page.MustElementR("label", "I understand, and I have saved the passphrase.").MustClick()
|
||||||
|
page.MustElementR("span", "Next >").MustClick()
|
||||||
|
|
||||||
|
// Verify that browser component has loaded and that the dropzone is present.
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
|
||||||
|
// Attempt to create an invalid folder.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
folderInput := page.MustElement("[placeholder=\"Name of the folder\"]")
|
||||||
|
folderInput.MustInput("...")
|
||||||
|
page.MustElementR("button", "Save Folder").MustProperty("disabled")
|
||||||
|
require.Equal(t, "...", folderInput.MustText(), "Folder input does not contain the `...` invalid name")
|
||||||
|
|
||||||
|
// Create a folder.
|
||||||
|
err := folderInput.SelectAllText()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
folderInput.MustInput("folderCreatedThroughInput")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "folderCreatedThroughInput")
|
||||||
|
|
||||||
|
// Navigate into the folder and make sure the dropzone is visible.
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "folderCreatedThroughInput").MustClick()
|
||||||
|
require.Equal(t, " folderCreatedThroughInput", page.MustElement("a[aria-current=\"page\"]").MustText(), "Navigating into the folder `folderCreatedThroughInput` has not been successful")
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
|
||||||
|
// Attempt to create a new folder but cancel.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("Hello World!")
|
||||||
|
page.MustElementR("button", "Cancel").MustClick()
|
||||||
|
|
||||||
|
// Add a file into folder and check that dropzone is still visible.
|
||||||
|
wait := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/img.png")
|
||||||
|
wait()
|
||||||
|
page.MustElementR("span", "folderCreatedThroughInput/img.png")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "img.png")
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
|
||||||
|
// Click on the file name.
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "img.png").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=image-preview]").MustProperty("src").Str(), "img.png", "The modal did not open on file click")
|
||||||
|
|
||||||
|
// Share a file.
|
||||||
|
page.MustElementR("span", "Share").MustClick()
|
||||||
|
page.MustElement("#generateShareLink")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Click on the hamburger and share.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Share").MustClick()
|
||||||
|
page.MustElement("#btn-copy-link")
|
||||||
|
page.MustElement("[aria-roledescription=close-share-modal]").MustClick()
|
||||||
|
|
||||||
|
// Click on the hamburger and then details.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Details").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=image-preview]").MustProperty("src").Str(), "img.png", "The dropdown details functionality is not working")
|
||||||
|
page.MustElementR("span", "Share").MustClick()
|
||||||
|
page.MustElement("#generateShareLink")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Use the `..` to navigate out of the folder.
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
page.MustElementR("a[aria-current=page]", "demo-bucket")
|
||||||
|
|
||||||
|
// Add another folder.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("go-rod-test3")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "go-rod-test3")
|
||||||
|
|
||||||
|
// Add two files.
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/img2.png")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/img.png")
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "img2.png")
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "img.png")
|
||||||
|
|
||||||
|
// Sort folders/files (by name, size, and date).
|
||||||
|
require.Equal(t, " folderCreatedThroughInput", page.MustElement("table > tbody > tr:nth-child(1) > td").MustText(), "The automatic sorting by name for folders is not working")
|
||||||
|
require.Equal(t, " img.png", page.MustElement("table > tbody > tr:nth-child(3) > td").MustText(), "The automatic sorting by name for files is not working")
|
||||||
|
page.MustElementR("th", "Name").MustClick()
|
||||||
|
require.Equal(t, " go-rod-test3", page.MustElement("table > tbody > tr:nth-child(1) > td").MustText(), "Sorting by name is not working for folders")
|
||||||
|
require.Equal(t, " img2.png", page.MustElement("table > tbody > tr:nth-child(3) > td").MustText(), "Sorting by name is not working for files")
|
||||||
|
// sort by size and date still left to do.
|
||||||
|
|
||||||
|
// Single folder select.
|
||||||
|
page.MustElement("table > tbody > tr:nth-child(1)").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("table > tbody > tr:nth-child(1)").String(), ".selected-row", "The clicked folder row has not been selected properly")
|
||||||
|
|
||||||
|
// Multifolder unselect.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
require.Equal(t, "false", fmt.Sprint(page.MustElement("table > tbody > tr:nth-child(1)").MustHas(".selected-row")), "Multiple selected folders were not unselected successfully")
|
||||||
|
|
||||||
|
// Single file select.
|
||||||
|
page.MustElement("table > tbody > tr:nth-child(3)").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("table > tbody > tr:nth-child(3)").String(), ".selected-row", "Single file select is not working properly")
|
||||||
|
// Multifile select **CAN'T SIMULATE MULTIPLE FILE SELECT YET**.
|
||||||
|
|
||||||
|
// Multifile unselect.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
require.Equal(t, "false", fmt.Sprint(page.MustElement("table > tbody > tr:nth-child(3)").MustHas(".selected-row")), "Multiple selected files were not unselected successfully")
|
||||||
|
|
||||||
|
// Select file and folders **CAN'T SIMULATE MULTIPLE FILE/FOLDERS SELECT YET**.
|
||||||
|
|
||||||
|
// Navigate into folders and use the breadcrumbs to navigate out.
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "go-rod-test3").MustClick()
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
page.MustElementR("a[aria-current=page]", "demo-bucket")
|
||||||
|
|
||||||
|
// Cancel folder deletion by way of hamburger.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
page.MustElementR("button", "No").MustClick()
|
||||||
|
page.MustElementR("a", "go-rod-test3")
|
||||||
|
|
||||||
|
// Delete a folder by clicking on hamburger.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
page.MustElementR("table > tbody > tr:nth-child(1) > td", "folderCreatedThroughInput")
|
||||||
|
|
||||||
|
// Cancel folder deletion by way of trashcan.
|
||||||
|
page.MustElement("tr[scope=\"row\"]").MustClick()
|
||||||
|
page.MustElement("#header-delete").MustClick()
|
||||||
|
page.MustElementR("button", "No").MustClick()
|
||||||
|
page.MustElementR("a[href=\"/objects/upload/folderCreatedThroughInput/\"]", "folderCreatedThroughInput")
|
||||||
|
|
||||||
|
// Delete a folder by selecting and clicking on trashcan.
|
||||||
|
page.MustElement("tr[scope=row]").MustClick()
|
||||||
|
page.MustElement("#header-delete").MustClick()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
page.MustElementR("table > tbody > tr:nth-child(1) > td", "img2.png")
|
||||||
|
|
||||||
|
// Cancel file deletion by way of hamburger.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
page.MustElementR("button", "No").MustClick()
|
||||||
|
require.Equal(t, " img2.png", page.MustElement("table > tbody > tr:nth-child(1) > td").MustText(), "File deletion cancellation by way of hamburger is not working")
|
||||||
|
|
||||||
|
// Delete a file by clicking on the hamburger.
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
page.MustElementR("table > tbody > tr:nth-child(1) > td", "img.png")
|
||||||
|
|
||||||
|
// Cancel file deletion by way of trashcan.
|
||||||
|
page.MustElement("tr[scope=row]").MustClick()
|
||||||
|
page.MustElement("#header-delete").MustClick()
|
||||||
|
page.MustElementR("button", "No").MustClick()
|
||||||
|
require.Equal(t, " img.png", page.MustElement("table > tbody > tr:nth-child(1) > td").MustText(), "File cancellation by way of trashcan is not working")
|
||||||
|
|
||||||
|
// Delete a file by clicking on the row and clicking on the trashcan.
|
||||||
|
wait2 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("tr[scope=row]").MustClick()
|
||||||
|
page.MustElement("#header-delete").MustClick()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
wait2()
|
||||||
|
|
||||||
|
// Delete multiple folders by selection **SELECTION NOT WORKING**.
|
||||||
|
|
||||||
|
// Delete multiple files by selection **SELECTION NOT WORKING**.
|
||||||
|
|
||||||
|
// Empty out entire folder.
|
||||||
|
|
||||||
|
// Attempt to create a folder with spaces.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput(" ")
|
||||||
|
page.MustElementR("button", "Save Folder").MustProperty("disabled")
|
||||||
|
require.Equal(t, " ", page.MustElement("[placeholder=\"Name of the folder\"]").MustText(), "Folder input does not contain the empty invalid name")
|
||||||
|
page.MustElementR("button", "Cancel").MustClick()
|
||||||
|
|
||||||
|
// Create Folder with special characters.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("Свобода")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "Свобода")
|
||||||
|
|
||||||
|
// Navigate into folder and create another folder of the same name, and check that the dropzone is present.
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "Свобода").MustClick()
|
||||||
|
page.MustElement("[href=\"/objects/upload/Свобода/\"]")
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("Свобода")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "Свобода")
|
||||||
|
|
||||||
|
// upload a video.
|
||||||
|
wait3 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/movie.mp4")
|
||||||
|
wait3()
|
||||||
|
page.MustElementR("span", "Свобода/movie.mp4")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "movie.mp4")
|
||||||
|
page.MustElementR("[aria-roledescription=file-size]", "1.48 kB")
|
||||||
|
page.MustElement("[aria-roledescription=file-upload-date]")
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "movie.mp4").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=video-preview]").MustProperty("src").Str(), "movie.mp4", "The modal did not open on video file click")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Upload an audio file.
|
||||||
|
wait4 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/audio.mp3")
|
||||||
|
wait4()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "audio.mp3").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=audio-preview]").MustProperty("src").Str(), "audio.mp3", "The modal did not open on video file click")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Navigate out of nested folder and delete everything.
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
wait5 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
wait5()
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,182 @@
|
|||||||
|
// Copyright (C) 2021 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package satellite_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"storj.io/common/memory"
|
||||||
|
"storj.io/common/testcontext"
|
||||||
|
"storj.io/storj/testsuite/ui/uitest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBrowserFolderAndDifferentFileSizesUpload(t *testing.T) {
|
||||||
|
uitest.Edge(t, func(t *testing.T, ctx *testcontext.Context, planet *uitest.EdgePlanet, browser *rod.Browser) {
|
||||||
|
page := openPage(browser, planet.Satellites[0].ConsoleURL())
|
||||||
|
|
||||||
|
// Sign up and login.
|
||||||
|
signUpWithUser(t, planet, page)
|
||||||
|
loginWithUser(t, planet, page)
|
||||||
|
|
||||||
|
// Navigate into browser with new onboarding.
|
||||||
|
page.MustElementR("a", "Skip and go directly to dashboard").MustClick()
|
||||||
|
page.MustElementR("p", "Objects").MustClick()
|
||||||
|
page.MustElementR("label", "I understand, and I have saved the passphrase.").MustClick()
|
||||||
|
page.MustElementR("span", "Next >").MustClick()
|
||||||
|
|
||||||
|
// Verify that browser component has loaded and that the dropzone is present.
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
|
||||||
|
// Create a Folder.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("testing")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "testing").MustClick()
|
||||||
|
|
||||||
|
// Attempt to create a folder with spaces.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput(" ")
|
||||||
|
require.Equal(t, "true", page.MustElementR("button", "Save Folder").MustProperty("disabled").Str(), "Folder is not disabled on invalid folder name with spaces")
|
||||||
|
require.Equal(t, " ", page.MustElement("[placeholder=\"Name of the folder\"]").MustText(), "Folder input does not contain the empty invalid name")
|
||||||
|
page.MustElementR("button", "Cancel").MustClick()
|
||||||
|
|
||||||
|
// Upload a folder (folder upload doesn't work when headless).
|
||||||
|
if os.Getenv("STORJ_TEST_SHOW_BROWSER") == "" {
|
||||||
|
// Create folder
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("testData")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
|
||||||
|
// Navigate into folder and upload file.
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "testData").MustClick()
|
||||||
|
page.MustElement("[href=\"/objects/upload/testing/testData/\"]")
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload").MustText()
|
||||||
|
|
||||||
|
// Attempt to create a folder with spaces.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput(" ")
|
||||||
|
require.Equal(t, "true", page.MustElementR("button", "Save Folder").MustProperty("disabled").Str(), "Folder is not disabled on invalid folder name with spaces")
|
||||||
|
require.Equal(t, " ", page.MustElement("[placeholder=\"Name of the folder\"]").MustText(), "Folder input does not contain the empty invalid name")
|
||||||
|
page.MustElementR("button", "Cancel").MustClick()
|
||||||
|
|
||||||
|
wait := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/test0bytes.txt")
|
||||||
|
wait()
|
||||||
|
page.MustElementR("span", "testing/testData/test0bytes.txt")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes.txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the test0bytes.txt file")
|
||||||
|
} else {
|
||||||
|
wait2 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=folder-upload]").MustSetFiles("./testdata")
|
||||||
|
wait2()
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "testdata").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes.txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The uploaded folder did not upload the files correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
|
||||||
|
// Upload duplicate folder (folder upload doesn't work when headless).
|
||||||
|
if os.Getenv("STORJ_TEST_SHOW_BROWSER") == "" {
|
||||||
|
// Create folder.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput("testdata (1)")
|
||||||
|
page.MustElementR("button", "Save Folder").MustClick()
|
||||||
|
|
||||||
|
// Navigate into folder and upload file.
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "testdata \\(1\\)").MustClick()
|
||||||
|
page.MustElement("[href=\"/objects/upload/testing/testdata (1)/\"]")
|
||||||
|
page.MustElementR("p", "Drop Files Here to Upload")
|
||||||
|
|
||||||
|
// Attempt to create a folder with spaces.
|
||||||
|
page.MustElementR("button", "New Folder").MustClick()
|
||||||
|
page.MustElement("[placeholder=\"Name of the folder\"]").MustInput(" ")
|
||||||
|
require.Equal(t, "true", page.MustElementR("button", "Save Folder").MustProperty("disabled").Str(), "Folder is not disabled on invalid folder name with spaces")
|
||||||
|
require.Equal(t, " ", page.MustElement("[placeholder=\"Name of the folder\"]").MustText(), "Folder input does not contain the empty invalid name")
|
||||||
|
page.MustElementR("button", "Cancel").MustClick()
|
||||||
|
|
||||||
|
wait3 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/test0bytes.txt")
|
||||||
|
wait3()
|
||||||
|
page.MustElementR("span", "testing/testdata \\(1\\)/test0bytes.txt")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes.txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the test0bytes.txt file")
|
||||||
|
} else {
|
||||||
|
wait4 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElement("input[aria-roledescription=folder-upload]").MustSetFiles("./testdata")
|
||||||
|
wait4()
|
||||||
|
page.MustElementR("table > tbody > tr:nth-child(1) > td", "..")
|
||||||
|
page.MustElementR("[aria-roledescription=folder]", "testdata \\(1\\)").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes.txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The uploaded folder did not upload the files correctly")
|
||||||
|
}
|
||||||
|
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
|
||||||
|
// Upload a 0 byte file.
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/test0bytes.txt")
|
||||||
|
page.MustElementR("span", "testing/test0bytes.txt")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes.txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the 0 byte file")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Upload duplicate 0 byte file.
|
||||||
|
page.MustElement("input[aria-roledescription=file-upload]").MustSetFiles("./testdata/test0bytes.txt")
|
||||||
|
page.MustElementR("[aria-roledescription=file]", "test0bytes \\(1\\).txt").MustClick()
|
||||||
|
require.Contains(t, page.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the duplicate file")
|
||||||
|
page.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
|
slowpage := page.Sleeper(uitest.MaxDuration(20 * time.Second))
|
||||||
|
|
||||||
|
// Upload a 50 MB file.
|
||||||
|
testFile := generateEmptyFile(t, ctx, "testFile", 5*memory.MiB)
|
||||||
|
wait5 := slowpage.MustWaitRequestIdle()
|
||||||
|
slowpage.MustElement("input[aria-roledescription=file-upload]").MustSetFiles(testFile)
|
||||||
|
wait5()
|
||||||
|
slowpage.MustElementR("[aria-roledescription=file]", "testFile").MustClick()
|
||||||
|
require.Contains(t, slowpage.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the 50 MB file")
|
||||||
|
slowpage.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Attempt to upload a large file and cancel the upload after a few segments have been uploaded successfully.
|
||||||
|
testFile2 := generateEmptyFile(t, ctx, "testFile2", 130*memory.MiB)
|
||||||
|
slowpage.MustElement("input[aria-roledescription=file-upload]").MustSetFiles(testFile2)
|
||||||
|
require.Equal(t, " testing/testFile2", slowpage.MustElement("[aria-roledescription=file-uploading]").MustText(), "The testFile2 file has not started uploading")
|
||||||
|
slowpage.MustElementR("[aria-roledescription=files-uploading-count]", "1 file waiting to be uploaded...")
|
||||||
|
slowpage.MustElementR("[aria-roledescription=progress-bar]", "1")
|
||||||
|
slowpage.MustElementR("button", "Cancel").MustClick()
|
||||||
|
slowpage.MustElementR("table > tbody > tr:nth-child(6) > td > span", "testFile")
|
||||||
|
slowpage.MustElementR("[aria-roledescription=file]", "testFile").MustClick()
|
||||||
|
slowpage.MustElement("#close-modal").MustClick()
|
||||||
|
|
||||||
|
// Upload a 130MB file.
|
||||||
|
wait6 := slowpage.MustWaitRequestIdle()
|
||||||
|
slowpage.MustElement("input[aria-roledescription=file-upload]").MustSetFiles(testFile2)
|
||||||
|
require.Equal(t, " testing/testFile2", slowpage.MustElement("[aria-roledescription=file-uploading]").MustText(), "The testFile2 file has not started uploading")
|
||||||
|
slowpage.MustElementR("[aria-roledescription=files-uploading-count]", "1 file waiting to be uploaded...")
|
||||||
|
wait6()
|
||||||
|
slowpage.MustElementR("[aria-roledescription=file]", "testFile2").MustClick()
|
||||||
|
require.Contains(t, slowpage.MustElement("[aria-roledescription=preview-placeholder]").String(), "svg", "The modal did not open upon clicking the 130MB file")
|
||||||
|
slowpage.MustElement("#close-modal").MustClick()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate out of nested folder and delete everything.
|
||||||
|
page.MustElement("#navigate-back").MustClick()
|
||||||
|
page.MustElement("button[aria-roledescription=dropdown]").MustClick()
|
||||||
|
page.MustElementR("button", "Delete").MustClick()
|
||||||
|
wait7 := page.MustWaitRequestIdle()
|
||||||
|
page.MustElementR("button", "Yes").MustClick()
|
||||||
|
wait7()
|
||||||
|
})
|
||||||
|
}
|
BIN
testsuite/ui/satellite/testdata/audio.mp3
vendored
Normal file
BIN
testsuite/ui/satellite/testdata/audio.mp3
vendored
Normal file
Binary file not shown.
BIN
testsuite/ui/satellite/testdata/img.png
vendored
Normal file
BIN
testsuite/ui/satellite/testdata/img.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 715 B |
BIN
testsuite/ui/satellite/testdata/img2.png
vendored
Normal file
BIN
testsuite/ui/satellite/testdata/img2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 715 B |
BIN
testsuite/ui/satellite/testdata/movie.mp4
vendored
Normal file
BIN
testsuite/ui/satellite/testdata/movie.mp4
vendored
Normal file
Binary file not shown.
0
testsuite/ui/satellite/testdata/test0bytes.txt
vendored
Normal file
0
testsuite/ui/satellite/testdata/test0bytes.txt
vendored
Normal file
@ -4,7 +4,16 @@
|
|||||||
package satellite_test
|
package satellite_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
|
"github.com/go-rod/rod/lib/input"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"storj.io/common/memory"
|
||||||
|
"storj.io/common/testcontext"
|
||||||
|
"storj.io/storj/testsuite/ui/uitest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func waitVueTick(page *rod.Page) {
|
func waitVueTick(page *rod.Page) {
|
||||||
@ -17,3 +26,46 @@ func openPage(browser *rod.Browser, url string) *rod.Page {
|
|||||||
page.MustNavigate(url).MustWaitLoad()
|
page.MustNavigate(url).MustWaitLoad()
|
||||||
return page
|
return page
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func signUpWithUser(t *testing.T, planet *uitest.EdgePlanet, page *rod.Page) {
|
||||||
|
signupPageURL := planet.Satellites[0].ConsoleURL() + "/signup"
|
||||||
|
fullName := "John Doe"
|
||||||
|
emailAddress := "test@email.com"
|
||||||
|
password := "qazwsx123"
|
||||||
|
|
||||||
|
// navigate to signup page
|
||||||
|
page.MustNavigate(signupPageURL)
|
||||||
|
|
||||||
|
// first time User signup
|
||||||
|
page.MustElement("[aria-roledescription=name] input").MustInput(fullName)
|
||||||
|
page.MustElement("[aria-roledescription=email] input").MustInput(emailAddress)
|
||||||
|
page.MustElement("[aria-roledescription=password] input").MustInput(password)
|
||||||
|
page.MustElement("[aria-roledescription=retype-password] input").MustInput(password)
|
||||||
|
page.MustElement(".checkmark").MustClick()
|
||||||
|
page.Keyboard.MustPress(input.Enter)
|
||||||
|
confirmAccountEmailMessage := page.MustElement("[aria-roledescription=title]").MustText()
|
||||||
|
require.Contains(t, confirmAccountEmailMessage, "You're almost there!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func loginWithUser(t *testing.T, planet *uitest.EdgePlanet, page *rod.Page) {
|
||||||
|
loginPageURL := planet.Satellites[0].ConsoleURL() + "/login"
|
||||||
|
emailAddress := "test@email.com"
|
||||||
|
password := "qazwsx123"
|
||||||
|
|
||||||
|
// navigate to login page
|
||||||
|
page.MustNavigate(loginPageURL)
|
||||||
|
|
||||||
|
// login
|
||||||
|
page.MustElement("[aria-roledescription=email] input").MustInput(emailAddress)
|
||||||
|
page.MustElement("[aria-roledescription=password] input").MustInput(password)
|
||||||
|
page.Keyboard.MustPress(input.Enter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateEmptyFile(t *testing.T, ctx *testcontext.Context, name string, size memory.Size) string {
|
||||||
|
path := ctx.File(name)
|
||||||
|
f, err := os.Create(path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { require.NoError(t, f.Close()) }()
|
||||||
|
require.NoError(t, f.Truncate(size.Int64()))
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
@ -46,7 +46,7 @@ func Browser(t *testing.T, ctx *testcontext.Context, fn func(*rod.Browser)) {
|
|||||||
Logger(zapWriter{Logger: logLauncher}).
|
Logger(zapWriter{Logger: logLauncher}).
|
||||||
Set("enable-logging").
|
Set("enable-logging").
|
||||||
Set("disable-gpu").
|
Set("disable-gpu").
|
||||||
Set("disable-web-security") // TODO: ensure we have proper CORS for testing
|
Set("disable-web-security") // TODO: ensure we have proper CORS for testing.
|
||||||
|
|
||||||
if browserHost := os.Getenv("STORJ_TEST_BROWER_HOSTPORT"); browserHost != "" {
|
if browserHost := os.Getenv("STORJ_TEST_BROWER_HOSTPORT"); browserHost != "" {
|
||||||
host, port, err := net.SplitHostPort(browserHost)
|
host, port, err := net.SplitHostPort(browserHost)
|
||||||
@ -70,7 +70,7 @@ func Browser(t *testing.T, ctx *testcontext.Context, fn func(*rod.Browser)) {
|
|||||||
|
|
||||||
browser := rod.New().
|
browser := rod.New().
|
||||||
Timeout(time.Minute).
|
Timeout(time.Minute).
|
||||||
Sleeper(func() utils.Sleeper { return timeoutSleeper(5*time.Second, 5) }).
|
Sleeper(MaxDuration(5 * time.Second)).
|
||||||
ControlURL(url).
|
ControlURL(url).
|
||||||
Logger(utils.Log(func(msg ...interface{}) {
|
Logger(utils.Log(func(msg ...interface{}) {
|
||||||
logBrowser.Info(fmt.Sprintln(msg...))
|
logBrowser.Info(fmt.Sprintln(msg...))
|
||||||
@ -106,27 +106,40 @@ func browserTimeoutDetector(duration time.Duration) context.CancelFunc {
|
|||||||
return cancel
|
return cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeoutSleeper(totalSleep time.Duration, maxTries int) utils.Sleeper {
|
// MaxDuration returns a sleeper constructor with the max duration.
|
||||||
singleSleep := totalSleep / time.Duration(maxTries)
|
func MaxDuration(max time.Duration) func() utils.Sleeper {
|
||||||
|
return func() utils.Sleeper {
|
||||||
|
singleSleep := 50 * time.Millisecond
|
||||||
|
totalSlept := time.Duration(0)
|
||||||
|
return func(ctx context.Context) error {
|
||||||
|
if totalSlept > max {
|
||||||
|
return errMaxSleepDuration(max)
|
||||||
|
}
|
||||||
|
if singleSleep > 500*time.Millisecond {
|
||||||
|
singleSleep = 500 * time.Millisecond
|
||||||
|
}
|
||||||
|
|
||||||
var slept int
|
totalSlept += singleSleep
|
||||||
return func(ctx context.Context) error {
|
t := time.NewTimer(singleSleep)
|
||||||
slept++
|
defer t.Stop()
|
||||||
if slept > maxTries {
|
select {
|
||||||
return &utils.ErrMaxSleepCount{Max: maxTries}
|
case <-t.C:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t := time.NewTimer(singleSleep)
|
|
||||||
defer t.Stop()
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
case <-ctx.Done():
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// errMaxSleepDuration is error for exceeding sleep duration.
|
||||||
|
type errMaxSleepDuration time.Duration
|
||||||
|
|
||||||
|
// Error implements error interface.
|
||||||
|
func (e errMaxSleepDuration) Error() string {
|
||||||
|
return fmt.Sprintf("max sleep %v exceeded", time.Duration(e))
|
||||||
|
}
|
||||||
|
|
||||||
func avoidStall(maxDuration time.Duration, fn func()) {
|
func avoidStall(maxDuration time.Duration, fn func()) {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -72,7 +72,7 @@ func Edge(t *testing.T, test EdgeTest) {
|
|||||||
config.Console.StaticDir = dir
|
config.Console.StaticDir = dir
|
||||||
}
|
}
|
||||||
config.Console.NewOnboarding = true
|
config.Console.NewOnboarding = true
|
||||||
config.Console.NewObjectsFlow = true
|
config.Console.NewBrowser = true
|
||||||
// TODO: this should be dynamically set from the auth service
|
// TODO: this should be dynamically set from the auth service
|
||||||
config.Console.GatewayCredentialsRequestURL = "http://" + authSvcAddr
|
config.Console.GatewayCredentialsRequestURL = "http://" + authSvcAddr
|
||||||
},
|
},
|
||||||
|
@ -41,6 +41,7 @@ func Run(t *testing.T, test Test) {
|
|||||||
}
|
}
|
||||||
config.Console.NewOnboarding = true
|
config.Console.NewOnboarding = true
|
||||||
config.Console.NewNavigation = true
|
config.Console.NewNavigation = true
|
||||||
|
config.Console.NewBrowser = true
|
||||||
config.Console.CouponCodeBillingUIEnabled = true
|
config.Console.CouponCodeBillingUIEnabled = true
|
||||||
config.Console.NewObjectsFlow = true
|
config.Console.NewObjectsFlow = true
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<div class="header-container__left-area__logo-area">
|
<div class="header-container__left-area__logo-area">
|
||||||
<NavigationMenuIcon
|
<NavigationMenuIcon
|
||||||
v-if="!isNavigationVisible && !isOnboardingTour"
|
v-if="!isNavigationVisible && !isOnboardingTour"
|
||||||
|
id="navigation-menu-icon"
|
||||||
class="header-container__left-area__logo-area__menu-button"
|
class="header-container__left-area__logo-area__menu-button"
|
||||||
@click.stop="toggleNavigationVisibility"
|
@click.stop="toggleNavigationVisibility"
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user