From e43f9ad7bb8d013865a7f474acf85ebcb34caf59 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Mon, 14 Jul 2025 14:14:38 +0545 Subject: [PATCH 1/4] Revert "test(refactor): remove vfs related tests" This reverts commit b3914432e0f2988c0ae77dd8aa0022ad9726b254. --- test/gui/shared/scripts/names.py | 1 + .../pageObjects/AccountConnectionWizard.py | 17 ++++ .../scripts/pageObjects/SyncConnection.py | 17 ++++ .../pageObjects/SyncConnectionWizard.py | 17 ++++ test/gui/shared/steps/account_context.py | 17 ++++ test/gui/shared/steps/sync_context.py | 23 +++++ test/gui/tst_addAccount/test.feature | 11 +++ test/gui/tst_syncing/test.feature | 13 ++- test/gui/tst_vfs/test.feature | 86 +++++++++++++++++++ test/gui/tst_vfs/test.py | 8 ++ 10 files changed, 203 insertions(+), 7 deletions(-) create mode 100644 test/gui/tst_vfs/test.feature create mode 100644 test/gui/tst_vfs/test.py diff --git a/test/gui/shared/scripts/names.py b/test/gui/shared/scripts/names.py index fabf00fb95..7b288f6c65 100644 --- a/test/gui/shared/scripts/names.py +++ b/test/gui/shared/scripts/names.py @@ -28,6 +28,7 @@ oCC_ShareLinkWidget_checkBox_expire_QProgressIndicator = {"aboveWidget": oCC_ShareLinkWidget_lineEdit_password_QLineEdit, "container": qt_tabwidget_stackedwidget_OCC_ShareLinkWidget_OCC_ShareLinkWidget, "leftWidget": oCC_ShareLinkWidget_checkBox_expire_QCheckBox, "type": "QProgressIndicator", "unnamed": 1, "visible": 1} settings_settingsdialog_toolbutton_Add_account_QToolButton = {"name": "settingsdialog_toolbutton_Add account", "type": "QToolButton", "visible": 1, "window": settings_OCC_SettingsDialog} settings_settingsdialog_toolbutton_Activity_QToolButton = {"name": "settingsdialog_toolbutton_Activity", "type": "QToolButton", "visible": 1, "window": settings_OCC_SettingsDialog} +disable_virtual_file_support_QMessageBox = {"type": "QMessageBox", "unnamed": 1, "visible": 1, "windowTitle": "Disable virtual file support?"} opencloudWizard_urlLabel_QLabel = {"name": "urlLabel", "type": "QLabel", "visible": 1, "window": opencloudWizard_OCC_OpencloudWizard} setupWizardWindow_OCC_Wizard_SetupWizardWindow = {"name": "SetupWizardWidget", "type": "OCC::Wizard::SetupWizardWidget", "visible": 1} setupWizardWindow_contentWidget_QStackedWidget = {"name": "contentWidget", "type": "QStackedWidget", "visible": 1, "window": setupWizardWindow_OCC_Wizard_SetupWizardWindow} diff --git a/test/gui/shared/scripts/pageObjects/AccountConnectionWizard.py b/test/gui/shared/scripts/pageObjects/AccountConnectionWizard.py index fd8359e2be..29d5013a03 100644 --- a/test/gui/shared/scripts/pageObjects/AccountConnectionWizard.py +++ b/test/gui/shared/scripts/pageObjects/AccountConnectionWizard.py @@ -95,6 +95,12 @@ class AccountConnectionWizard: "type": "QLineEdit", "visible": 1, } + VIRTUAL_FILE_RADIO_BUTTON = { + "container": names.advancedConfigGroupBox_syncModeGroupBox_QGroupBox, + "name": "useVfsRadioButton", + "type": "QRadioButton", + "visible": 1, + } SYNC_EVERYTHING_RADIO_BUTTON = { "container": names.advancedConfigGroupBox_syncModeGroupBox_QGroupBox, "name": "syncEverythingRadioButton", @@ -211,6 +217,11 @@ def select_manual_sync_folder_option(): ) ) + @staticmethod + def select_vfs_option(): + squish.clickButton( + squish.waitForObject(AccountConnectionWizard.VIRTUAL_FILE_RADIO_BUTTON) + ) @staticmethod def select_download_everything_option(): @@ -268,6 +279,12 @@ def is_sync_everything_option_checked(): AccountConnectionWizard.SYNC_EVERYTHING_RADIO_BUTTON ).checked + @staticmethod + def is_vfs_option_checked(): + return squish.waitForObjectExists( + AccountConnectionWizard.VIRTUAL_FILE_RADIO_BUTTON + ).checked + @staticmethod def get_local_sync_path(): return str( diff --git a/test/gui/shared/scripts/pageObjects/SyncConnection.py b/test/gui/shared/scripts/pageObjects/SyncConnection.py index eb0e16966c..f13eee97a0 100644 --- a/test/gui/shared/scripts/pageObjects/SyncConnection.py +++ b/test/gui/shared/scripts/pageObjects/SyncConnection.py @@ -30,6 +30,12 @@ class SyncConnection: "unnamed": 1, "visible": True } + DISABLE_VFS_CONFIRMATION_BUTTON = { + "text": "Disable support", + "type": "QPushButton", + "visible": 1, + "window": names.disable_virtual_file_support_QMessageBox, + } SELECTIVE_SYNC_APPLY_BUTTON = { "container": names.settings_stack_QStackedWidget, "name": "selectiveSyncApply", @@ -79,6 +85,17 @@ def pause_sync(): def resume_sync(): SyncConnection.perform_action("Resume sync") + @staticmethod + def enable_vfs(): + SyncConnection.perform_action("Enable virtual file support") + + @staticmethod + def disable_vfs(): + SyncConnection.perform_action("Disable virtual file support") + squish.clickButton( + squish.waitForObject(SyncConnection.DISABLE_VFS_CONFIRMATION_BUTTON) + ) + @staticmethod def has_menu_item(item): return squish.waitForObjectItem(SyncConnection.MENU, item) diff --git a/test/gui/shared/scripts/pageObjects/SyncConnectionWizard.py b/test/gui/shared/scripts/pageObjects/SyncConnectionWizard.py index 68f446b89d..222581e915 100644 --- a/test/gui/shared/scripts/pageObjects/SyncConnectionWizard.py +++ b/test/gui/shared/scripts/pageObjects/SyncConnectionWizard.py @@ -51,6 +51,13 @@ class SyncConnectionWizard: "type": "QTreeWidget", "visible": 1, } + VFS_CHECKBOX = { + "text": "Use virtual files instead of downloading content immediately", + "type": "QCheckBox", + "unnamed": 1, + "visible": 1, + "window": names.add_Folder_Sync_Connection_OCC_FolderWizard, + } SELECTIVE_SYNC_TREE_HEADER = { "container": names.add_Space_Deselect_remote_folders_you_do_not_wish_to_synchronize_QTreeWidget, "orientation": 1, @@ -160,6 +167,16 @@ def deselect_all_remote_folders(): squish.Qt.LeftButton, ) + @staticmethod + def enable_disable_vfs_support(action="disable"): + if action not in ["enable", "disable"]: + raise ValueError("Invalid action: " + action) + + checked = squish.waitForObjectExists(SyncConnectionWizard.VFS_CHECKBOX).checked + if (action == "enable") == checked: + return + squish.clickButton(squish.waitForObject(SyncConnectionWizard.VFS_CHECKBOX)) + @staticmethod def select_folders_to_sync(folders): # first deselect all diff --git a/test/gui/shared/steps/account_context.py b/test/gui/shared/steps/account_context.py index d51611bbfe..07d185e6ba 100644 --- a/test/gui/shared/steps/account_context.py +++ b/test/gui/shared/steps/account_context.py @@ -203,6 +203,12 @@ def step(context): ) +@When('the user selects vfs option in advanced section') +def step(context): + AccountConnectionWizard.select_vfs_option() + AccountConnectionWizard.next_step() + + @When('the user selects download everything option in advanced section') def step(context): AccountConnectionWizard.select_download_everything_option() @@ -228,6 +234,17 @@ def step(context): 'Sync everything option is checked', ) + +@Then('the VFS option should be selected by default for Windows') +def step(context): + if is_windows(): + test.compare( + True, + AccountConnectionWizard.is_vfs_option_checked(), + 'VFS option is checked', + ) + + @When(r'^the user presses the "([^"]*)" key(?:s)?', regexp=True) def step(context, key): AccountSetting.press_key(key) diff --git a/test/gui/shared/steps/sync_context.py b/test/gui/shared/steps/sync_context.py index 8fbd6616e4..ca150130a3 100644 --- a/test/gui/shared/steps/sync_context.py +++ b/test/gui/shared/steps/sync_context.py @@ -60,6 +60,14 @@ def step(context, username, resource_type, resource): wait_for_resource_to_have_sync_error(resource, resource_type) +@When('the user enables virtual file support') +def step(context): + SyncConnection.enable_vfs() + # TODO: remove snooze with proper wait + # let the client re-sync + squish.snooze(get_config('minSyncTimeout')) + + @Then('the "|any|" button should be available') def step(context, item): SyncConnection.open_menu() @@ -76,6 +84,14 @@ def step(context, item): ) +@When('the user disables virtual file support') +def step(context): + SyncConnection.disable_vfs() + # TODO: remove snooze with proper wait + # let the client re-sync + squish.snooze(get_config('minSyncTimeout')) + + @When('the user clicks on the activity tab') def step(context): Toolbar.open_activity() @@ -215,6 +231,13 @@ def step(context): SyncConnectionWizard.deselect_all_remote_folders() +@When('the user |word| VFS support for Windows') +def step(context, action): + if is_windows(): + action = action.rstrip('s') + SyncConnectionWizard.enable_disable_vfs_support(action) + + @When('user unselects a folder "|any|" in selective sync') def step(context, folder_name): SyncConnection.choose_what_to_sync() diff --git a/test/gui/tst_addAccount/test.feature b/test/gui/tst_addAccount/test.feature index 5fd616f165..1a35dfbdf3 100644 --- a/test/gui/tst_addAccount/test.feature +++ b/test/gui/tst_addAccount/test.feature @@ -15,6 +15,7 @@ Feature: adding accounts | password | 1234 | When the user opens the advanced configuration Then the download everything option should be selected by default for Linux + And the VFS option should be selected by default for Windows And the user should be able to choose the local download directory @@ -50,6 +51,16 @@ Feature: adding accounts | password | 1234 | Then "Alice Hansen" account should be opened + @skipOnLinux + Scenario: Adding account with vfs disabled (Windows only) + Given the user has started the client + And the user has entered the following account information: + | server | %local_server% | + | user | Alice | + | password | 1234 | + When the user selects download everything option in advanced section + Then the "Enable virtual file support" button should be available + Scenario: Add space manually from sync connection window Given user "Alice" has created folder "simple-folder" in the server diff --git a/test/gui/tst_syncing/test.feature b/test/gui/tst_syncing/test.feature index b14f92ed50..06816d67cd 100644 --- a/test/gui/tst_syncing/test.feature +++ b/test/gui/tst_syncing/test.feature @@ -56,6 +56,7 @@ Feature: Syncing files client content """ + Scenario: Sync all is selected by default Given user "Alice" has created folder "simple-folder" in the server And user "Alice" has created folder "large-folder" in the server @@ -71,6 +72,7 @@ Feature: Syncing files And the user sets the sync path in sync connection wizard And the user navigates back in the sync connection wizard And the user sets the temp folder "localSyncFolder" as local sync path in sync connection wizard + And the user disables VFS support for Windows Then the sync all checkbox should be checked When user unselects all the remote folders And the user adds the folder sync connection @@ -80,6 +82,7 @@ Feature: Syncing files But the folder "simple-folder" should not exist on the file system And the folder "large-folder" should not exist on the file system + Scenario: Sync only one folder from the server Given user "Alice" has created folder "simple-folder" in the server And user "Alice" has created folder "large-folder" in the server @@ -91,6 +94,7 @@ Feature: Syncing files When the user selects manual sync folder option in advanced section And the user selects "Personal" space in sync connection wizard And the user sets the sync path in sync connection wizard + And the user disables VFS support for Windows And the user selects the following folders to sync: | folder | | simple-folder | @@ -125,6 +129,7 @@ Feature: Syncing files When the user selects manual sync folder option in advanced section And the user selects "Personal" space in sync connection wizard And the user sets the sync path in sync connection wizard + And the user disables VFS support for Windows # folders are sorted by name in ascending order by default Then the folders should be in the following order: | folder | @@ -465,6 +470,7 @@ Feature: Syncing files When the user selects manual sync folder option in advanced section And the user selects "Personal" space in sync connection wizard And the user sets the temp folder "~`!@#$^&()-_=+{[}];',)PRN%" as local sync path in sync connection wizard + And the user disables VFS support for Windows And the user selects the following folders to sync: | folder | | ~`!@#$^&()-_=+{[}];',) | @@ -479,13 +485,6 @@ Feature: Syncing files And the folder "test-folder/sub-folder2" should exist on the file system And the folder "test-folder/sub-folder1" should not exist on the file system - - Scenario: Syncing a local folder having special characters to the server - Given user "Alice" has set up a client with default settings - When user "Alice" creates a folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" inside the sync folder - And the user waits for folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" to be synced - Then as "Alice" folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" should exist in the server - @issue-11814 Scenario: remove folder sync connection Given user "Alice" has created folder "simple-folder" in the server diff --git a/test/gui/tst_vfs/test.feature b/test/gui/tst_vfs/test.feature new file mode 100644 index 0000000000..dd9448283c --- /dev/null +++ b/test/gui/tst_vfs/test.feature @@ -0,0 +1,86 @@ +@skipOnLinux +Feature: Enable/disable virtual file support + As a user + I want to enable virtual file support + So that I can synchronize virtual files with local folder + + + Scenario: Disable/Enable VFS + Given user "Alice" has been created in the server with default attributes + And user "Alice" has uploaded file with content "openCloud" to "testFile.txt" in the server + And user "Alice" has created folder "folder1" in the server + And user "Alice" has uploaded file with content "some contents" to "folder1/lorem.txt" in the server + And user "Alice" has created folder "folder2" in the server + And user "Alice" has uploaded file with content "content" to "folder2/lorem.txt" in the server + And user "Alice" has set up a client with default settings + Then the placeholder of file "testFile.txt" should exist on the file system + And the placeholder of file "folder1/lorem.txt" should exist on the file system + And the placeholder of file "folder2/lorem.txt" should exist on the file system + And the "Choose what to sync" button should not be available + When the user disables virtual file support + Then the "Enable virtual file support" button should be available + And the file "testFile.txt" should be downloaded + And the file "folder1/lorem.txt" should be downloaded + And the file "folder2/lorem.txt" should be downloaded + When user unselects a folder "folder1" in selective sync + And the user waits for the files to sync + Then the folder "folder1" should not exist on the file system + And the file "folder2/lorem.txt" should exist on the file system + When the user enables virtual file support + Then the "Disable virtual file support" button should be available + And the placeholder of file "folder1/lorem.txt" should exist on the file system + And the file "testFile.txt" should be downloaded + And the file "folder2/lorem.txt" should be downloaded + + + Scenario: Copy and paste virtual file + Given user "Alice" has been created in the server with default attributes + And user "Alice" has uploaded file with content "sample file" to "sampleFile.txt" in the server + And user "Alice" has uploaded file with content "lorem file" to "lorem.txt" in the server + And user "Alice" has uploaded file with content "test file" to "testFile.txt" in the server + And user "Alice" has created folder "Folder" in the server + And user "Alice" has set up a client with default settings + Then the placeholder of file "lorem.txt" should exist on the file system + And the placeholder of file "sampleFile.txt" should exist on the file system + And the placeholder of file "testFile.txt" should exist on the file system + When user "Alice" copies file "sampleFile.txt" to temp folder + And the user copies the file "lorem.txt" to "Folder" + And the user copies the file "testFile.txt" to "testFile.txt" + And the user waits for file "Folder/lorem.txt" to be synced + Then the file "sampleFile.txt" should be downloaded + And the file "Folder/lorem.txt" should be downloaded + And the file "lorem.txt" should be downloaded + And the file "testFile.txt" should be downloaded + And the file "testFile - Copy.txt" should be downloaded + And as "Alice" file "Folder/lorem.txt" should exist in the server + And as "Alice" file "lorem.txt" should exist in the server + And as "Alice" file "sampleFile.txt" should exist in the server + And as "Alice" file "testFile.txt" should exist in the server + And as "Alice" file "testFile - Copy.txt" should exist in the server + + + Scenario: Move virtual file + Given user "Alice" has been created in the server with default attributes + And user "Alice" has uploaded file with content "lorem file" to "lorem.txt" in the server + And user "Alice" has uploaded file with content "some contents" to "sampleFile.txt" in the server + And user "Alice" has created folder "Folder" in the server + And user "Alice" has set up a client with default settings + When user "Alice" moves file "lorem.txt" to "Folder" in the sync folder + And user "Alice" moves file "sampleFile.txt" to the temp folder + And the user waits for file "Folder/lorem.txt" to be synced + Then the placeholder of file "Folder/lorem.txt" should exist on the file system + And as "Alice" file "Folder/lorem.txt" should exist in the server + And as "Alice" file "lorem.txt" should not exist in the server + And as "Alice" file "sampleFile.txt" should not exist in the server + + + Scenario: Disable/Enable VFS quickly + Given user "Alice" has been created in the server with default attributes + And user "Alice" has set up a client with default settings + When user "Alice" creates a file "newfile.txt" with size "100MB" inside the sync folder + And the user waits for file "newfile.txt" to be synced + And the user disables virtual file support + And the user enables virtual file support + And the user disables virtual file support + And the user enables virtual file support + Then the "Disable virtual file support" button should be available diff --git a/test/gui/tst_vfs/test.py b/test/gui/tst_vfs/test.py new file mode 100644 index 0000000000..83b0a5275a --- /dev/null +++ b/test/gui/tst_vfs/test.py @@ -0,0 +1,8 @@ +source(findFile('scripts', 'python/bdd.py')) + +setupHooks('../shared/scripts/bdd_hooks.py') +collectStepDefinitions('./steps', '../shared/steps') + + +def main(): + runFeatureFile('test.feature') From 902d808bb61039f6468d8bd0293ca6103b255680 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Mon, 14 Jul 2025 16:15:08 +0545 Subject: [PATCH 2/4] wait for file to exist before checking size --- test/gui/shared/scripts/helpers/FilesHelper.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/gui/shared/scripts/helpers/FilesHelper.py b/test/gui/shared/scripts/helpers/FilesHelper.py index a417dc0276..f2994fde6e 100644 --- a/test/gui/shared/scripts/helpers/FilesHelper.py +++ b/test/gui/shared/scripts/helpers/FilesHelper.py @@ -3,6 +3,7 @@ import ctypes import shutil +import squish from helpers.ConfigHelper import is_windows, get_config @@ -93,8 +94,10 @@ def get_size_in_bytes(size): def get_file_size_on_disk(resource_path): - file_size_high = ctypes.c_ulonglong(0) if is_windows(): + timeout = get_config('maxSyncTimeout') * 1000 + squish.waitFor(lambda: os.path.exists(resource_path), timeout) + file_size_high = ctypes.c_ulonglong(0) return ctypes.windll.kernel32.GetCompressedFileSizeW( ctypes.c_wchar_p(resource_path), ctypes.pointer(file_size_high) ) From 2ace00b714d7aa123d06358774d0aa2e00d52e67 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Mon, 14 Jul 2025 16:24:29 +0545 Subject: [PATCH 3/4] enable vfs in client config --- test/gui/shared/scripts/helpers/SetupClientHelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gui/shared/scripts/helpers/SetupClientHelper.py b/test/gui/shared/scripts/helpers/SetupClientHelper.py index 02216c1162..596319b4a4 100644 --- a/test/gui/shared/scripts/helpers/SetupClientHelper.py +++ b/test/gui/shared/scripts/helpers/SetupClientHelper.py @@ -169,7 +169,7 @@ def generate_account_config(users, space='Personal'): settings.setValue("localPath", sync_path) settings.setValue("paused", 'false') settings.setValue("priority", '50') - settings.setValue("virtualFilesMode", 'off') + settings.setValue("virtualFilesMode", 'cfapi') settings.setValue("journalPath",".sync_journal.db") settings.endArray() settings.setValue("size", len(users)) From 1e3ff29af29962677a3b99b285f91fda1610d55c Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Mon, 14 Jul 2025 16:44:51 +0545 Subject: [PATCH 4/4] fix rebasing problem --- test/gui/tst_syncing/test.feature | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/gui/tst_syncing/test.feature b/test/gui/tst_syncing/test.feature index 06816d67cd..98e302ac4a 100644 --- a/test/gui/tst_syncing/test.feature +++ b/test/gui/tst_syncing/test.feature @@ -56,7 +56,6 @@ Feature: Syncing files client content """ - Scenario: Sync all is selected by default Given user "Alice" has created folder "simple-folder" in the server And user "Alice" has created folder "large-folder" in the server @@ -485,6 +484,13 @@ Feature: Syncing files And the folder "test-folder/sub-folder2" should exist on the file system And the folder "test-folder/sub-folder1" should not exist on the file system + + Scenario: Syncing a local folder having special characters to the server + Given user "Alice" has set up a client with default settings + When user "Alice" creates a folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" inside the sync folder + And the user waits for folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" to be synced + Then as "Alice" folder "~`!@#$^&()-_=+{[}];',)💥🫨❤️‍🔥" should exist in the server + @issue-11814 Scenario: remove folder sync connection Given user "Alice" has created folder "simple-folder" in the server