Initial QSfera import
This commit is contained in:
@@ -0,0 +1,292 @@
|
||||
import shutil
|
||||
import os
|
||||
from behave import given as Given, when as When, then as Then
|
||||
from sure import expect, ensure
|
||||
|
||||
from pageObjects.AccountConnectionWizard import AccountConnectionWizard
|
||||
from pageObjects.SyncConnectionWizard import SyncConnectionWizard
|
||||
from pageObjects.AccountSetting import AccountSetting
|
||||
from pageObjects.Toolbar import Toolbar
|
||||
from pageObjects.EnterPassword import EnterPassword
|
||||
from helpers.SetupClientHelper import (
|
||||
start_client,
|
||||
setup_client,
|
||||
substitute_inline_codes,
|
||||
get_client_details,
|
||||
generate_account_config,
|
||||
get_resource_path,
|
||||
)
|
||||
from helpers.SyncHelper import (
|
||||
wait_for_initial_sync_to_complete,
|
||||
listen_sync_status_for_item,
|
||||
)
|
||||
from helpers.UserHelper import get_displayname_for_user, get_password_for_user
|
||||
from helpers.ConfigHelper import get_config
|
||||
from helpers.TableParser import table_rows_hash
|
||||
from helpers.AppHelper import close_and_kill_app
|
||||
|
||||
|
||||
@Given('the user has started the client')
|
||||
def step(context):
|
||||
start_client()
|
||||
|
||||
|
||||
@When('the user adds the following user credentials:')
|
||||
def step(context):
|
||||
account_details = get_client_details(context)
|
||||
set_config('syncConnectionName', get_displayname_for_user(account_details['user']))
|
||||
AccountConnectionWizard.add_user_credentials(
|
||||
account_details['user'], account_details['password']
|
||||
)
|
||||
|
||||
|
||||
@Then('"{username}" account should be added')
|
||||
def step(context, username):
|
||||
username = substitute_inline_codes(username)
|
||||
expect(Toolbar.account_exists(username)).to.be.true
|
||||
|
||||
|
||||
@Then('"{username}" account should not be displayed')
|
||||
def step(context, username):
|
||||
username = substitute_inline_codes(username)
|
||||
expect(Toolbar.account_exists(username)).to.be.false
|
||||
|
||||
|
||||
@Given('user "{username}" has set up a client with default settings')
|
||||
def step(context, username):
|
||||
password = get_password_for_user(username)
|
||||
setup_client(username)
|
||||
enter_password = EnterPassword()
|
||||
enter_password.accept_certificate()
|
||||
|
||||
enter_password.login_after_setup(username, password)
|
||||
|
||||
# wait for files to sync
|
||||
wait_for_initial_sync_to_complete(get_resource_path('/', username))
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@Given('the user has set up the following accounts with default settings:')
|
||||
def step(context):
|
||||
users = []
|
||||
for row in context.table:
|
||||
users.append(row[0])
|
||||
sync_paths = generate_account_config(users)
|
||||
start_client()
|
||||
# accept certificate for each user
|
||||
for idx, _ in enumerate(users):
|
||||
enter_password = EnterPassword()
|
||||
enter_password.accept_certificate()
|
||||
|
||||
for idx, _ in enumerate(sync_paths.values()):
|
||||
# login from last dialog
|
||||
enter_password = EnterPassword()
|
||||
username = enter_password.get_username()
|
||||
password = get_password_for_user(username)
|
||||
listen_sync_status_for_item(sync_paths[username])
|
||||
enter_password.login_after_setup(username, password)
|
||||
# wait for files to sync
|
||||
wait_for_initial_sync_to_complete(sync_paths[username])
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@When('the user starts the client')
|
||||
def step(context):
|
||||
start_client()
|
||||
|
||||
|
||||
@When('the user opens the add-account dialog')
|
||||
def step(context):
|
||||
Toolbar.open_new_account_setup()
|
||||
|
||||
|
||||
@When('the user adds the following account:')
|
||||
def step(context):
|
||||
data = table_rows_hash(context.table)
|
||||
account_details = get_client_details(data)
|
||||
AccountConnectionWizard.add_account(account_details)
|
||||
# # wait for files to sync
|
||||
wait_for_initial_sync_to_complete(get_resource_path('/', account_details['user']))
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@Given('the user has entered the following account information:')
|
||||
def step(context):
|
||||
data = table_rows_hash(context.table)
|
||||
account_details = get_client_details(data)
|
||||
AccountConnectionWizard.add_account_information(account_details)
|
||||
|
||||
|
||||
@When('the user "{username}" logs out using the client-UI')
|
||||
def step(context, username):
|
||||
AccountSetting.logout()
|
||||
|
||||
|
||||
@Then('user "{username}" should be signed out')
|
||||
def step(context, username):
|
||||
user_signed_out = AccountSetting.is_user_signed_out()
|
||||
|
||||
with ensure('User "{0}" should be signed out, but is still signed in', username):
|
||||
user_signed_out.should.be.true
|
||||
|
||||
|
||||
@Given('user "{username}" has logged out from the client-UI')
|
||||
def step(context, username):
|
||||
AccountSetting.logout()
|
||||
if not AccountSetting.is_user_signed_out():
|
||||
raise LookupError(f'Failed to logout user {username}')
|
||||
|
||||
|
||||
@When('user "{username}" logs in using the client-UI')
|
||||
def step(context, username):
|
||||
AccountSetting.login()
|
||||
password = get_password_for_user(username)
|
||||
enter_password = EnterPassword()
|
||||
enter_password.relogin(username, password)
|
||||
|
||||
# wait for files to sync
|
||||
wait_for_initial_sync_to_complete(get_resource_path('/', username))
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@When('user "|any|" opens login dialog')
|
||||
def step(context, _):
|
||||
AccountSetting.login()
|
||||
|
||||
|
||||
@Then('user "{username}" should be connected to the server')
|
||||
def step(context, username):
|
||||
AccountSetting.wait_until_account_is_connected()
|
||||
|
||||
|
||||
@When('the user removes the connection for user "{username}"')
|
||||
def step(context, username):
|
||||
username = substitute_inline_codes(username)
|
||||
AccountSetting.remove_connection_for_user(username)
|
||||
|
||||
|
||||
@Then('connection wizard should be visible')
|
||||
def step(context):
|
||||
test.compare(
|
||||
AccountConnectionWizard.is_new_connection_window_visible(),
|
||||
True,
|
||||
'Connection window is visible',
|
||||
)
|
||||
|
||||
|
||||
@When('the user accepts the certificate')
|
||||
def step(context):
|
||||
AccountConnectionWizard.accept_certificate()
|
||||
|
||||
|
||||
@When('the user adds the server "|any|"')
|
||||
def step(context, server):
|
||||
server_url = substitute_inline_codes(server)
|
||||
AccountConnectionWizard.add_server(server_url)
|
||||
|
||||
|
||||
@When('the user selects manual sync folder option in advanced section')
|
||||
def step(context):
|
||||
AccountConnectionWizard.select_manual_sync_folder_option()
|
||||
AccountConnectionWizard.next_step()
|
||||
|
||||
|
||||
@Then('credentials wizard should be visible')
|
||||
def step(context):
|
||||
test.compare(
|
||||
AccountConnectionWizard.is_credential_window_visible(),
|
||||
True,
|
||||
'Credentials wizard is visible',
|
||||
)
|
||||
|
||||
|
||||
@When('the user selects download everything option in advanced section')
|
||||
def step(context):
|
||||
AccountConnectionWizard.select_download_everything_option()
|
||||
AccountConnectionWizard.next_step()
|
||||
|
||||
|
||||
@When('the user opens the advanced configuration')
|
||||
def step(context):
|
||||
AccountConnectionWizard.select_advanced_config()
|
||||
|
||||
|
||||
@Then('the user should be able to choose the local download directory')
|
||||
def step(context):
|
||||
test.compare(True, AccountConnectionWizard.can_change_local_sync_dir())
|
||||
|
||||
|
||||
@Then('the download everything option should be selected by default for Linux')
|
||||
def step(context):
|
||||
if is_linux():
|
||||
test.compare(
|
||||
True,
|
||||
AccountConnectionWizard.is_sync_everything_option_checked(),
|
||||
'Sync everything option is checked',
|
||||
)
|
||||
|
||||
|
||||
@When(r'^the user presses the "([^"]*)" key(?:s)?', regexp=True)
|
||||
def step(context, key):
|
||||
AccountSetting.press_key(key)
|
||||
|
||||
|
||||
@Then('the log dialog should be opened')
|
||||
def step(context):
|
||||
test.compare(True, AccountSetting.is_log_dialog_visible(), 'Log dialog is opened')
|
||||
|
||||
|
||||
@When('the user cancels the sync connection wizard')
|
||||
def step(context):
|
||||
SyncConnectionWizard.cancel_folder_sync_connection_wizard()
|
||||
|
||||
|
||||
@When('the user quits the client')
|
||||
def step(context):
|
||||
Toolbar.quit_qsfera()
|
||||
close_and_kill_app()
|
||||
|
||||
|
||||
@Then('"{username}" account should be opened')
|
||||
def step(context, username):
|
||||
username = substitute_inline_codes(username)
|
||||
expect(Toolbar.account_has_focus(username)).to.be.true
|
||||
|
||||
|
||||
@Then(
|
||||
r'the default local sync path should contain "([^"]*)" in the (configuration|sync connection) wizard',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, sync_path, wizard):
|
||||
sync_path = substitute_inline_codes(sync_path)
|
||||
|
||||
actual_sync_path = ''
|
||||
|
||||
if wizard == 'configuration':
|
||||
actual_sync_path = AccountConnectionWizard.get_local_sync_path()
|
||||
else:
|
||||
actual_sync_path = SyncConnectionWizard.get_local_sync_path()
|
||||
|
||||
test.compare(
|
||||
actual_sync_path,
|
||||
convert_path_separators_for_os(sync_path),
|
||||
'Compare sync path contains the expected path',
|
||||
)
|
||||
|
||||
|
||||
@Then('the warning "|any|" should appear in the sync connection wizard')
|
||||
def step(context, warn_message):
|
||||
actual_message = SyncConnectionWizard.get_warn_label()
|
||||
test.compare(
|
||||
True,
|
||||
warn_message in actual_message,
|
||||
'Contains warning message',
|
||||
)
|
||||
|
||||
|
||||
@Given('the user has removed the connection for user "{username}"')
|
||||
def step(context, username):
|
||||
username = substitute_inline_codes(username)
|
||||
AccountSetting.remove_connection_for_user(username)
|
||||
AccountSetting.wait_until_account_is_removed(username)
|
||||
shutil.rmtree(os.path.join(get_config("clientRootSyncPath"), username))
|
||||
@@ -0,0 +1,458 @@
|
||||
import os
|
||||
import re
|
||||
import builtins
|
||||
import shutil
|
||||
import zipfile
|
||||
from os.path import isfile, join, isdir, exists
|
||||
from behave import when as When, then as Then
|
||||
from sure import ensure
|
||||
|
||||
from helpers.SetupClientHelper import get_resource_path, get_temp_resource_path
|
||||
from helpers.SyncHelper import (
|
||||
wait_for_client_to_be_ready,
|
||||
listen_sync_status_for_item,
|
||||
wait_for,
|
||||
)
|
||||
from helpers.ConfigHelper import get_config, is_windows
|
||||
from helpers.FilesHelper import (
|
||||
build_conflicted_regex,
|
||||
sanitize_path,
|
||||
can_read,
|
||||
can_write,
|
||||
read_file_content,
|
||||
get_size_in_bytes,
|
||||
prefix_path_namespace,
|
||||
remember_path,
|
||||
convert_path_separators_for_os,
|
||||
get_file_for_upload,
|
||||
)
|
||||
|
||||
|
||||
def folder_exists(folder_path, timeout=1000):
|
||||
return wait_for(
|
||||
lambda: isdir(sanitize_path(folder_path)),
|
||||
timeout,
|
||||
)
|
||||
|
||||
|
||||
def file_exists(file_path, timeout=1000):
|
||||
return wait_for(
|
||||
lambda: isfile(sanitize_path(file_path)),
|
||||
timeout,
|
||||
)
|
||||
|
||||
|
||||
# To create folders in a temporary directory, we set is_temp_folder True
|
||||
# And if is_temp_folder is True, the create_folder function create folders in tempFolderPath
|
||||
def create_folder(foldername, username=None, is_temp_folder=False):
|
||||
if is_temp_folder:
|
||||
folder_path = join(get_config('tempFolderPath'), foldername)
|
||||
else:
|
||||
folder_path = get_resource_path(foldername, username)
|
||||
os.makedirs(prefix_path_namespace(convert_path_separators_for_os(folder_path)))
|
||||
|
||||
|
||||
def rename_file_folder(source, destination):
|
||||
source = get_resource_path(source)
|
||||
destination = get_resource_path(destination)
|
||||
os.rename(source, destination)
|
||||
|
||||
|
||||
def create_file_with_size(filename, filesize, is_temp_folder=False):
|
||||
if is_temp_folder:
|
||||
file = join(get_config('tempFolderPath'), filename)
|
||||
else:
|
||||
file = get_resource_path(filename)
|
||||
with open(prefix_path_namespace(file), 'wb') as f:
|
||||
f.seek(get_size_in_bytes(filesize) - 1)
|
||||
f.write(b'\0')
|
||||
|
||||
|
||||
def write_file(resource, content):
|
||||
with open(prefix_path_namespace(resource), 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def wait_and_write_file(path, content):
|
||||
wait_for_client_to_be_ready()
|
||||
listen_sync_status_for_item(get_resource_path(path), 'FILE')
|
||||
write_file(path, content)
|
||||
|
||||
|
||||
def wait_and_try_to_write_file(resource, content):
|
||||
wait_for_client_to_be_ready()
|
||||
listen_sync_status_for_item(get_resource_path(resource), 'FILE')
|
||||
try:
|
||||
write_file(resource, content)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def create_zip(resources, zip_file_name, cwd=''):
|
||||
os.chdir(cwd)
|
||||
with zipfile.ZipFile(zip_file_name, 'w') as zipped_file:
|
||||
for resource in resources:
|
||||
zipped_file.write(resource)
|
||||
|
||||
|
||||
def extract_zip(zip_file_path, destination_dir):
|
||||
with zipfile.ZipFile(zip_file_path, 'r') as zip_file:
|
||||
zip_file.extractall(destination_dir)
|
||||
|
||||
|
||||
def add_copy_suffix(resource_path, resource_type):
|
||||
suffix = ' (Copy)'
|
||||
if resource_type == 'file':
|
||||
source_dir = resource_path.rsplit('.', 1)
|
||||
return source_dir[0] + suffix + '.' + source_dir[-1]
|
||||
return resource_path + suffix
|
||||
|
||||
|
||||
def copy_resource(resource_type, source, destination, from_files_for_upload=False):
|
||||
if from_files_for_upload:
|
||||
source = get_file_for_upload(source)
|
||||
else:
|
||||
source = get_resource_path(source)
|
||||
destination = get_resource_path(destination)
|
||||
if source == destination and destination != '/':
|
||||
destination = add_copy_suffix(source, resource_type)
|
||||
|
||||
wait_for_client_to_be_ready()
|
||||
listen_sync_status_for_item(destination, resource_type)
|
||||
if resource_type == 'folder':
|
||||
return shutil.copytree(source, destination)
|
||||
return shutil.copy2(source, destination)
|
||||
|
||||
|
||||
def move_resource(username, resource_type, source, destination, is_temp_folder=False):
|
||||
if not is_temp_folder:
|
||||
source = get_resource_path(source, username)
|
||||
if destination == '/':
|
||||
destination = ''
|
||||
destination = get_resource_path(destination, username)
|
||||
|
||||
wait_for_client_to_be_ready()
|
||||
listen_sync_status_for_item(destination, resource_type)
|
||||
shutil.move(source, destination)
|
||||
|
||||
|
||||
def deleteResource(resource, resource_type):
|
||||
wait_for_client_to_be_ready()
|
||||
listen_sync_status_for_item(resource, resource_type)
|
||||
resource_path = sanitize_path(get_resource_path(resource))
|
||||
if resource_type == 'file':
|
||||
os.remove(resource_path)
|
||||
else:
|
||||
shutil.rmtree(resource_path)
|
||||
|
||||
|
||||
@When(
|
||||
'user "{username}" creates a file "{filename}" with the following content inside the sync folder'
|
||||
)
|
||||
def step(context, username, filename):
|
||||
file = get_resource_path(filename, username)
|
||||
wait_and_write_file(convert_path_separators_for_os(file), context.text)
|
||||
|
||||
|
||||
@When('user "{username}" creates a folder "{foldername}" inside the sync folder')
|
||||
def step(context, username, foldername):
|
||||
wait_for_client_to_be_ready()
|
||||
create_folder(foldername, username)
|
||||
|
||||
|
||||
@Given('user "{username}" has created a folder "{foldername}" inside the sync folder')
|
||||
def step(context, username, foldername):
|
||||
create_folder(foldername, username)
|
||||
|
||||
|
||||
@When(
|
||||
'user "{user}" creates a file "{filename}" with size "{filesize}" inside the sync folder'
|
||||
)
|
||||
def step(context, user, filename, filesize):
|
||||
create_file_with_size(filename, filesize)
|
||||
|
||||
|
||||
@When(r'the user copies (file|folder) "([^"]*)" into folder "([^"]*)"', regexp=True)
|
||||
def step(context, resource_type, resource_name, destination_dir):
|
||||
copy_resource(resource_type, resource_name, destination_dir, False)
|
||||
|
||||
|
||||
@When(
|
||||
'the user copies {resource_type:ResourceType} "{resource_name}" into the same directory'
|
||||
)
|
||||
def step(context, resource_type, resource_name):
|
||||
copy_resource(resource_type, resource_name, resource_name, False)
|
||||
|
||||
|
||||
@When('the user renames a file "{source}" to "{destination}"')
|
||||
@When('the user renames a folder "{source}" to "{destination}"')
|
||||
def step(context, source, destination):
|
||||
wait_for_client_to_be_ready()
|
||||
rename_file_folder(source, destination)
|
||||
|
||||
|
||||
@Then(
|
||||
'the file "{file_path}" should exist on the file system with the following content'
|
||||
)
|
||||
def step(context, file_path):
|
||||
expected = context.text
|
||||
file_path = get_resource_path(file_path)
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
contents = f.read()
|
||||
with ensure(
|
||||
'{0} expected to exist with content "{1}" but has content "{2}"',
|
||||
file_path,
|
||||
expected,
|
||||
contents,
|
||||
):
|
||||
contents.should.equal(expected)
|
||||
|
||||
|
||||
@Then('the {resource_type:ResourceType} "{resource}" should exist on the file system')
|
||||
def step(context, resource_type, resource):
|
||||
resource_path = get_resource_path(resource)
|
||||
resource_exists = False
|
||||
timeout = get_config('maxSyncTimeout') * 1000
|
||||
if resource_type == 'file':
|
||||
resource_exists = file_exists(resource_path, timeout)
|
||||
else:
|
||||
resource_exists = folder_exists(resource_path, timeout)
|
||||
|
||||
with ensure(
|
||||
'{0} "{1}" should exist, but it does not',
|
||||
resource_type.capitalize(),
|
||||
resource,
|
||||
):
|
||||
resource_exists.should.be.true
|
||||
|
||||
|
||||
@Then(
|
||||
'the {resource_type:ResourceType} "{resource}" should not exist on the file system'
|
||||
)
|
||||
def step(context, resource_type, resource):
|
||||
resource_path = get_resource_path(resource)
|
||||
with ensure(
|
||||
'{0} "{1}" should not exist, but it does',
|
||||
resource_type.capitalize(),
|
||||
resource,
|
||||
):
|
||||
exists(resource_path).should.be.false
|
||||
|
||||
|
||||
@Given('the user has changed the content of local file "|any|" to:')
|
||||
def step(context, filename):
|
||||
file_content = '\n'.join(context.multiLineText)
|
||||
wait_and_write_file(get_resource_path(filename), file_content)
|
||||
|
||||
|
||||
@Then(
|
||||
'a conflict file for "|any|" should exist on the file system with the following content'
|
||||
)
|
||||
def step(context, filename):
|
||||
expected = '\n'.join(context.multiLineText)
|
||||
|
||||
onlyfiles = [
|
||||
f for f in os.listdir(get_resource_path()) if isfile(get_resource_path(f))
|
||||
]
|
||||
found = False
|
||||
pattern = re.compile(build_conflicted_regex(filename))
|
||||
for file in onlyfiles:
|
||||
if pattern.match(file):
|
||||
with open(get_resource_path(file), 'r', encoding='utf-8') as f:
|
||||
if f.read() == expected:
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
raise AssertionError('Conflict file not found with given name')
|
||||
|
||||
|
||||
@When('the user overwrites the file "{resource}" with content "{content}"')
|
||||
def step(context, resource, content):
|
||||
resource = get_resource_path(resource)
|
||||
wait_and_write_file(resource, content)
|
||||
|
||||
|
||||
@When('the user tries to overwrite the file "|any|" with content "|any|"')
|
||||
def step(context, resource, content):
|
||||
resource = get_resource_path(resource)
|
||||
wait_and_try_to_write_file(resource, content)
|
||||
|
||||
|
||||
@When('user "|any|" tries to overwrite the file "|any|" with content "|any|"')
|
||||
def step(context, user, resource, content):
|
||||
resource = get_resource_path(resource, user)
|
||||
wait_and_try_to_write_file(resource, content)
|
||||
|
||||
|
||||
@When('the user deletes the {resource_type:ResourceType} "{resource_name}"')
|
||||
def step(context, resource_type, resource_name):
|
||||
deleteResource(resource_name, resource_type)
|
||||
|
||||
|
||||
@When('user "|any|" creates the following files inside the sync folder:')
|
||||
def step(context, username):
|
||||
for row in context.table[1:]:
|
||||
file = get_resource_path(row[0], username)
|
||||
wait_and_write_file(file, '')
|
||||
|
||||
|
||||
@Given('the user has created a folder "|any|" in temp folder')
|
||||
def step(context, folder_name):
|
||||
create_folder(folder_name, is_temp_folder=True)
|
||||
|
||||
|
||||
@Given(
|
||||
'the user has created "|any|" files each of size "|any|" bytes inside folder "|any|" in temp folder'
|
||||
)
|
||||
def step(context, file_number, file_size, folder_name):
|
||||
current_sync_path = get_temp_resource_path(folder_name)
|
||||
if folder_exists(current_sync_path):
|
||||
file_size = builtins.int(file_size)
|
||||
for i in range(0, builtins.int(file_number)):
|
||||
file_name = f'file{i}.txt'
|
||||
create_file_with_size(join(current_sync_path, file_name), file_size, True)
|
||||
else:
|
||||
raise FileNotFoundError(
|
||||
f"Folder '{folder_name}' does not exist in the temp folder"
|
||||
)
|
||||
|
||||
|
||||
@When(
|
||||
r'user "([^"]*)" reads the content of file "([^"]*)"',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, username, file):
|
||||
file_path = get_resource_path(file, username)
|
||||
with open(file_path, 'r') as f:
|
||||
f.read()
|
||||
|
||||
|
||||
@When(
|
||||
r'user "([^"]*)" moves (folder|file) "([^"]*)" from the temp folder into the sync folder',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, username, resource_type, resource_name):
|
||||
source_dir = join(get_config('tempFolderPath'), resource_name)
|
||||
move_resource(username, resource_type, source_dir, '/', True)
|
||||
|
||||
|
||||
@When(
|
||||
r'user "([^"]*)" moves (folder|file) "([^"]*)" to the temp folder',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, username, resource_type, resource_name):
|
||||
destination = join(get_config('tempFolderPath'), resource_name)
|
||||
move_resource(username, resource_type, resource_name, destination)
|
||||
|
||||
|
||||
@When(
|
||||
'user "{username}" moves {resource_type:ResourceType} "{source}" to "{destination}" in the sync folder'
|
||||
)
|
||||
def step(context, username, resource_type, source, destination):
|
||||
move_resource(username, resource_type, source, destination)
|
||||
|
||||
|
||||
@Then('user "{user}" should be able to open the file "{file_name}" on the file system')
|
||||
def step(context, user, file_name):
|
||||
file_path = get_resource_path(file_name, user)
|
||||
with ensure(
|
||||
'File should be readable but user "{0}" cannot read file "{1}"',
|
||||
user,
|
||||
file_name,
|
||||
):
|
||||
can_read(file_path).should.be.true
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user}" the file "{file_name}" should have content "{content}" on the file system'
|
||||
)
|
||||
def step(context, user, file_name, content):
|
||||
file_path = get_resource_path(file_name, user)
|
||||
file_content = read_file_content(file_path)
|
||||
with ensure(
|
||||
'File "{0}" should have content "{1}" but got "{2}"',
|
||||
file_name,
|
||||
content,
|
||||
file_content,
|
||||
):
|
||||
content.should.equal(file_content)
|
||||
|
||||
|
||||
@Then('user "|any|" should not be able to edit the file "|any|" on the file system')
|
||||
def step(context, user, file_name):
|
||||
file_path = get_resource_path(file_name, user)
|
||||
test.compare(not can_write(file_path), True, 'File should not be writable')
|
||||
|
||||
|
||||
@Given(
|
||||
'the user has created a zip file "|any|" with the following resources in the temp folder'
|
||||
)
|
||||
def step(context, zip_file_name):
|
||||
resource_list = []
|
||||
|
||||
for row in context.table[1:]:
|
||||
resource_list.append(row[0])
|
||||
resource = join(get_config('tempFolderPath'), row[0])
|
||||
if row[1] == 'folder':
|
||||
os.makedirs(resource)
|
||||
elif row[1] == 'file':
|
||||
content = ''
|
||||
if len(row) > 2 and row[2]:
|
||||
content = row[2]
|
||||
write_file(resource, content)
|
||||
create_zip(resource_list, zip_file_name, get_config('tempFolderPath'))
|
||||
|
||||
|
||||
@When('user "|any|" unzips the zip file "|any|" inside the sync root')
|
||||
def step(context, username, zip_file_name):
|
||||
destination_dir = get_resource_path('/', username)
|
||||
zip_file_path = join(destination_dir, zip_file_name)
|
||||
extract_zip(zip_file_path, destination_dir)
|
||||
|
||||
|
||||
@When('user "|any|" copies file "|any|" to temp folder')
|
||||
def step(context, username, source):
|
||||
wait_for_client_to_be_ready()
|
||||
source_dir = get_resource_path(source, username)
|
||||
destination_dir = get_temp_resource_path(source)
|
||||
shutil.copy2(source_dir, destination_dir)
|
||||
|
||||
|
||||
@Given('the user has created folder "|any|" in the default home path')
|
||||
def step(context, folder_name):
|
||||
folder_path = join(get_config('home_dir'), folder_name)
|
||||
os.makedirs(prefix_path_namespace(folder_path))
|
||||
remember_path(folder_path)
|
||||
# when account is added, folder with suffix will be created
|
||||
remember_path(f'{folder_path} (2)')
|
||||
|
||||
|
||||
@Given(
|
||||
r'the user has copied file "([^"]*)" from outside the sync folder to "([^"]*)" in the sync folder',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, resource_name, destination):
|
||||
copy_resource('file', resource_name, destination, True)
|
||||
|
||||
|
||||
@When(
|
||||
r'the user copies file "([^"]*)" from outside the sync folder to "([^"]*)" in the sync folder',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, resource_name, destination):
|
||||
copy_resource('file', resource_name, destination, True)
|
||||
|
||||
|
||||
@When('the user deletes the following files')
|
||||
def step(context):
|
||||
wait_for_client_to_be_ready()
|
||||
|
||||
for row in context.table[1:]:
|
||||
filename = row[0]
|
||||
deleteResource(filename, 'file')
|
||||
|
||||
|
||||
@Given('user "|any|" has created a file "|any|" with size "|any|" in the sync folder')
|
||||
def step(context, _, filename, filesize):
|
||||
create_file_with_size(filename, filesize)
|
||||
@@ -0,0 +1,148 @@
|
||||
from behave import given as Given, then as Then
|
||||
from sure import ensure
|
||||
|
||||
from helpers.api import provisioning, webdav_helper as webdav
|
||||
from helpers.TableParser import table_rows_hash
|
||||
|
||||
|
||||
@Given('user "{user}" has been created in the server with default attributes')
|
||||
def step(context, user):
|
||||
provisioning.create_user(user)
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user_name}" {resource_type:ResourceType} "{resource_name}" should not exist in the server'
|
||||
)
|
||||
def step(context, user_name, resource_type, resource_name):
|
||||
resource_exists = webdav.resource_exists(user_name, resource_name)
|
||||
|
||||
with ensure(
|
||||
'{0} "{1}" should not exist, but it does',
|
||||
resource_type.capitalize(),
|
||||
resource_name,
|
||||
):
|
||||
resource_exists.should.be.false
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user_name}" {resource_type:ResourceType} "{resource_name}" should exist in the server'
|
||||
)
|
||||
def step(context, user_name, resource_type, resource_name):
|
||||
resource_exists = webdav.resource_exists(user_name, resource_name)
|
||||
|
||||
with ensure(
|
||||
'{0} "{1}" should exist, but it does not',
|
||||
resource_type.capitalize(),
|
||||
resource_name,
|
||||
):
|
||||
resource_exists.should.be.true
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user_name}" the file "{file_name}" should have the content "{content}" in the server'
|
||||
)
|
||||
def step(context, user_name, file_name, content):
|
||||
text_content = webdav.get_file_content(user_name, file_name)
|
||||
with ensure(
|
||||
'{0} should have content "{1}" but found "{2}"',
|
||||
file_name,
|
||||
content,
|
||||
text_content,
|
||||
):
|
||||
text_content.should.equal(content)
|
||||
|
||||
|
||||
@Then(
|
||||
r'as user "([^"].*)" folder "([^"].*)" should contain "([^"].*)" items in the server',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, user_name, folder_name, items_number):
|
||||
total_items = webdav.get_folder_items_count(user_name, folder_name)
|
||||
test.compare(
|
||||
total_items, items_number, f'Folder should contain {items_number} items'
|
||||
)
|
||||
|
||||
|
||||
@Given('user "{user}" has created folder "{folder_name}" in the server')
|
||||
def step(context, user, folder_name):
|
||||
webdav.create_folder(user, folder_name)
|
||||
|
||||
|
||||
@Given(
|
||||
'user "{user}" has uploaded file with content "{file_content}" to "{file_name}" in the server'
|
||||
)
|
||||
def step(context, user, file_content, file_name):
|
||||
webdav.create_file(user, file_name, file_content)
|
||||
|
||||
|
||||
@When('the user clicks on the settings tab')
|
||||
def step(context):
|
||||
Toolbar.open_settings_tab()
|
||||
|
||||
|
||||
@When('user "{user}" uploads file with content "{file_content}" to "{file_name}" in the server')
|
||||
def step(context, user, file_content, file_name):
|
||||
webdav.create_file(user, file_name, file_content)
|
||||
|
||||
|
||||
@When('user "{user}" deletes the folder "{folder_name}" in the server')
|
||||
def step(context, user, folder_name):
|
||||
webdav.delete_resource(user, folder_name)
|
||||
|
||||
|
||||
@Given('user "{user}" has uploaded file "{file_name}" to "{destination}" in the server')
|
||||
def step(context, user, file_name, destination):
|
||||
webdav.upload_file(user, file_name, destination)
|
||||
|
||||
|
||||
@Then(
|
||||
'as "|any|" the content of file "|any|" in the server should match the content of local file "|any|"'
|
||||
)
|
||||
def step(context, user_name, server_file_name, local_file_name):
|
||||
raw_server_content = webdav.get_file_content(user_name, server_file_name)
|
||||
with tempfile.NamedTemporaryFile(suffix=Path(server_file_name).suffix) as tmp_file:
|
||||
if isinstance(raw_server_content, str):
|
||||
tmp_file.write(raw_server_content.encode('utf-8'))
|
||||
else:
|
||||
tmp_file.write(raw_server_content)
|
||||
server_content = get_document_content(tmp_file.name)
|
||||
local_content = get_document_content(get_file_for_upload(local_file_name))
|
||||
|
||||
test.compare(
|
||||
server_content,
|
||||
local_content,
|
||||
f"Server file '{server_file_name}' differs from local file '{local_file_name}'",
|
||||
)
|
||||
|
||||
|
||||
@Then(
|
||||
r'as "([^"].*)" following files should not exist in the server',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, user_name):
|
||||
for row in context.table[1:]:
|
||||
resource_name = row[0]
|
||||
test.compare(
|
||||
webdav.resource_exists(user_name, resource_name),
|
||||
False,
|
||||
f"Resource '{resource_name}' should not exist, but does",
|
||||
)
|
||||
|
||||
|
||||
@Given('user "|any|" has uploaded the following files to the server')
|
||||
def step(context, user):
|
||||
for row in context.table[1:]:
|
||||
file_name = row[0]
|
||||
file_content = row[1]
|
||||
webdav.create_file(user, file_name, file_content)
|
||||
|
||||
|
||||
@Given('user "{user}" has sent the following resource share invitation:')
|
||||
def step(context, user):
|
||||
resource_details = table_rows_hash(context.table)
|
||||
webdav.send_resource_share_invitation(
|
||||
user,
|
||||
resource_details['resource'],
|
||||
resource_details['sharee'],
|
||||
resource_details['permissionsRole'],
|
||||
)
|
||||
@@ -0,0 +1,80 @@
|
||||
from sure import ensure
|
||||
|
||||
from pageObjects.EnterPassword import EnterPassword
|
||||
from pageObjects.Toolbar import Toolbar
|
||||
from helpers.UserHelper import get_password_for_user
|
||||
from helpers.SetupClientHelper import setup_client, get_resource_path
|
||||
from helpers.SyncHelper import wait_for_initial_sync_to_complete
|
||||
from helpers.SpaceHelper import (
|
||||
create_space,
|
||||
create_space_folder,
|
||||
create_space_file,
|
||||
add_user_to_space,
|
||||
get_file_content,
|
||||
resource_exists,
|
||||
)
|
||||
from helpers.ConfigHelper import get_config, set_config
|
||||
|
||||
|
||||
@Given('the administrator has created a space "{space_name}"')
|
||||
def step(context, space_name):
|
||||
create_space(space_name)
|
||||
|
||||
|
||||
@Given('the administrator has created a folder "{folder_name}" in space "{space_name}"')
|
||||
def step(context, folder_name, space_name):
|
||||
create_space_folder(space_name, folder_name)
|
||||
|
||||
|
||||
@Given(
|
||||
'the administrator has uploaded a file "{file_name}" with content "{content}" inside space "{space_name}"'
|
||||
)
|
||||
def step(context, file_name, content, space_name):
|
||||
create_space_file(space_name, file_name, content)
|
||||
|
||||
|
||||
@Given(
|
||||
'the administrator has added user "{user}" to space "{space_name}" with role "{role}"'
|
||||
)
|
||||
def step(context, user, space_name, role):
|
||||
add_user_to_space(user, space_name, role)
|
||||
|
||||
|
||||
@Given('user "{user}" has set up a client with space "{space_name}"')
|
||||
def step(context, user, space_name):
|
||||
set_config('syncConnectionName', space_name)
|
||||
password = get_password_for_user(user)
|
||||
setup_client(user, space_name)
|
||||
enter_password = EnterPassword()
|
||||
enter_password.accept_certificate()
|
||||
enter_password.login_after_setup(user, password)
|
||||
# wait for files to sync
|
||||
wait_for_initial_sync_to_complete(get_resource_path('/', user, space_name))
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user}" the file "{file_name}" in the space "{space_name}" should have content "{content}" in the server'
|
||||
)
|
||||
def step(context, user, file_name, space_name, content):
|
||||
downloaded_content = get_file_content(space_name, file_name, user)
|
||||
with ensure(
|
||||
'File "{0}" in space "{1}" should have content "{2}" but got "{3}"',
|
||||
file_name,
|
||||
space_name,
|
||||
content,
|
||||
downloaded_content,
|
||||
):
|
||||
content.should.equal(downloaded_content)
|
||||
|
||||
|
||||
@Then(
|
||||
'as "{user}" the space "{space_name}" should have file "{resource_name}" in the server'
|
||||
)
|
||||
@Then(
|
||||
'as "{user}" the space "{space_name}" should have folder "{resource_name}" in the server'
|
||||
)
|
||||
def step(context, user, space_name, resource_name):
|
||||
exists = resource_exists(space_name, resource_name, user)
|
||||
with ensure('Resource "{0}" should exist but it does not', resource_name):
|
||||
exists.should.be.true
|
||||
@@ -0,0 +1,377 @@
|
||||
from behave import when as When, then as Then
|
||||
from sure import ensure
|
||||
|
||||
from pageObjects.SyncConnectionWizard import SyncConnectionWizard
|
||||
from pageObjects.Toolbar import Toolbar
|
||||
from pageObjects.Activity import Activity
|
||||
from pageObjects.SyncConnection import SyncConnection
|
||||
from pageObjects.Settings import Settings
|
||||
from helpers.ConfigHelper import set_config
|
||||
from helpers.SyncHelper import (
|
||||
wait_for_resource_to_sync,
|
||||
wait_for_resource_to_have_sync_error,
|
||||
)
|
||||
from helpers.SetupClientHelper import (
|
||||
get_temp_resource_path,
|
||||
set_current_user_sync_path,
|
||||
substitute_inline_codes,
|
||||
get_resource_path,
|
||||
)
|
||||
from helpers.FilesHelper import convert_path_separators_for_os
|
||||
from helpers.TableParser import table_hashes, table_raw
|
||||
|
||||
|
||||
@Given('the user has paused the file sync')
|
||||
def step(context):
|
||||
SyncConnection.pause_sync()
|
||||
|
||||
|
||||
@When('the user resumes the file sync on the client')
|
||||
def step(context):
|
||||
SyncConnection.resume_sync()
|
||||
|
||||
|
||||
@When('the user force syncs the files')
|
||||
def step(context):
|
||||
SyncConnection.force_sync()
|
||||
|
||||
|
||||
@When('the user waits for the files to sync')
|
||||
def step(context):
|
||||
wait_for_resource_to_sync(get_resource_path('/'), force_sync=True)
|
||||
|
||||
|
||||
@When('the user waits for {resource_type:ResourceType} "{resource}" to be synced')
|
||||
def step(context, resource_type, resource):
|
||||
resource = get_resource_path(resource)
|
||||
wait_for_resource_to_sync(convert_path_separators_for_os(resource), resource_type)
|
||||
Toolbar.wait_toolbar_enabled()
|
||||
|
||||
|
||||
@When(r'the user waits for (file|folder) "([^"]*)" to have sync error', regexp=True)
|
||||
def step(context, resource_type, resource):
|
||||
resource = get_resource_path(resource)
|
||||
wait_for_resource_to_have_sync_error(resource, resource_type)
|
||||
|
||||
|
||||
@When(
|
||||
r'user "([^"]*)" waits for (file|folder) "([^"]*)" to have sync error', regexp=True
|
||||
)
|
||||
def step(context, username, resource_type, resource):
|
||||
resource = get_resource_path(resource, username)
|
||||
wait_for_resource_to_have_sync_error(resource, resource_type)
|
||||
|
||||
|
||||
@Then('the "|any|" button should be available')
|
||||
def step(context, item):
|
||||
SyncConnection.open_menu()
|
||||
SyncConnection.has_menu_item(item)
|
||||
|
||||
|
||||
@Then('the "|any|" button should not be available')
|
||||
def step(context, item):
|
||||
SyncConnection.open_menu()
|
||||
test.compare(
|
||||
SyncConnection.menu_item_exists(item),
|
||||
False,
|
||||
f'Menu item "{item}" does not exist.',
|
||||
)
|
||||
|
||||
|
||||
@When('the user opens the activity tab')
|
||||
def step(context):
|
||||
Toolbar.open_activity()
|
||||
|
||||
|
||||
@When('the user opens the settings tab')
|
||||
def step(context):
|
||||
Toolbar.open_settings_tab()
|
||||
|
||||
|
||||
@Then('the table of conflict warnings should include file "|any|"')
|
||||
def step(context, filename):
|
||||
Activity.check_file_exist(filename)
|
||||
|
||||
|
||||
@Then('the file "|any|" should be blacklisted')
|
||||
def step(context, filename):
|
||||
test.compare(
|
||||
True, Activity.is_resource_blacklisted(filename), 'File is Blacklisted'
|
||||
)
|
||||
|
||||
|
||||
@Then('the file "|any|" should be ignored')
|
||||
def step(context, filename):
|
||||
test.compare(True, Activity.is_resource_ignored(filename), 'File is Ignored')
|
||||
|
||||
|
||||
@Then('the file "|any|" should be excluded')
|
||||
def step(context, filename):
|
||||
test.compare(True, Activity.is_resource_excluded(filename), 'File is Excluded')
|
||||
|
||||
|
||||
@When('the user selects "{tab_name}" tab in the activity')
|
||||
def step(context, tab_name):
|
||||
Activity.click_tab(tab_name)
|
||||
|
||||
|
||||
@Then('the toolbar should have the following tabs:')
|
||||
def step(context):
|
||||
tabs = table_raw(context.table)
|
||||
for tab_name in tabs:
|
||||
tab_name = tab_name[0]
|
||||
with ensure('Tab not found: {0}', tab_name):
|
||||
Toolbar.has_tab(tab_name).should.be.true
|
||||
|
||||
|
||||
@When('the user selects the following folders to sync:')
|
||||
def step(context):
|
||||
folders = []
|
||||
for row in context.table:
|
||||
folders.append(row[0])
|
||||
SyncConnectionWizard.select_folders_to_sync(
|
||||
folders, new_sync_connection_wizard=True
|
||||
)
|
||||
|
||||
|
||||
@When('the user sorts the folder list by "|any|"')
|
||||
def step(context, header_text):
|
||||
if (header_text := header_text.capitalize()) in ['Size', 'Name']:
|
||||
SyncConnectionWizard.sort_by(header_text)
|
||||
else:
|
||||
raise ValueError("Sorting by '" + header_text + "' is not supported.")
|
||||
|
||||
|
||||
@Then('the sync all checkbox should be checked')
|
||||
def step(context):
|
||||
test.compare(
|
||||
SyncConnectionWizard.is_root_folder_checked(),
|
||||
True,
|
||||
'Sync all checkbox is checked',
|
||||
)
|
||||
|
||||
|
||||
@Then('the folders should be in the following order:')
|
||||
def step(context):
|
||||
row_index = 0
|
||||
for row in context.table[1:]:
|
||||
expected_folder = row[0]
|
||||
actual_folder = SyncConnectionWizard.get_item_name_from_row(row_index)
|
||||
test.compare(actual_folder, expected_folder)
|
||||
|
||||
row_index += 1
|
||||
|
||||
|
||||
@When('the user selects "{space_name}" space in sync connection wizard')
|
||||
def step(context, space_name):
|
||||
SyncConnectionWizard.select_space(space_name)
|
||||
SyncConnectionWizard.next_step()
|
||||
set_config('syncConnectionName', space_name)
|
||||
|
||||
|
||||
@When('the user sets the sync path in sync connection wizard')
|
||||
def step(context):
|
||||
SyncConnectionWizard.set_sync_path()
|
||||
|
||||
|
||||
@When(
|
||||
'the user sets the temp folder "|any|" as local sync path in sync connection wizard'
|
||||
)
|
||||
def step(context, folder_name):
|
||||
sync_path = get_temp_resource_path(folder_name)
|
||||
SyncConnectionWizard.set_sync_path(sync_path)
|
||||
set_current_user_sync_path(sync_path)
|
||||
|
||||
|
||||
@When('the user syncs the "{space_name}" space')
|
||||
def step(context, space_name):
|
||||
SyncConnectionWizard.sync_space(space_name)
|
||||
|
||||
|
||||
@Then('the settings tab should have the following options in the general section:')
|
||||
def step(context):
|
||||
settings = table_raw(context.table)
|
||||
for setting in settings:
|
||||
setting = setting[0]
|
||||
with ensure('General setting not found: {0}', setting):
|
||||
Settings.has_general_setting(setting).should.be.true
|
||||
|
||||
|
||||
@Then('the settings tab should have the following options in the advanced section:')
|
||||
def step(context):
|
||||
settings = table_raw(context.table)
|
||||
for setting in settings:
|
||||
setting = setting[0]
|
||||
with ensure('Advanced setting not found: {0}', setting):
|
||||
Settings.has_advanced_setting(setting).should.be.true
|
||||
|
||||
|
||||
@Then('the settings tab should have the following options in the network section:')
|
||||
def step(context):
|
||||
settings = table_raw(context.table)
|
||||
for setting in settings:
|
||||
setting = setting[0]
|
||||
with ensure('Network setting not found: {0}', setting):
|
||||
Settings.has_network_setting(setting).should.be.true
|
||||
|
||||
|
||||
@When('the user opens the about dialog')
|
||||
def step(context):
|
||||
Settings.open_about_dialog()
|
||||
|
||||
|
||||
@Then('the about dialog should be opened')
|
||||
def step(context):
|
||||
with ensure('About dialog is not opened.'):
|
||||
Settings.has_about_dialog().should.be.true
|
||||
|
||||
|
||||
@When('the user closes the about dialog')
|
||||
def step(context):
|
||||
Settings.close_about_dialog()
|
||||
|
||||
|
||||
@When('the user adds the folder sync connection')
|
||||
def step(context):
|
||||
SyncConnectionWizard.add_sync_connection()
|
||||
|
||||
|
||||
@When('user unselects all the remote folders')
|
||||
def step(context):
|
||||
SyncConnectionWizard.deselect_all_remote_folders()
|
||||
|
||||
|
||||
@Then('for user "{user}" sync folder "{sync_folder}" should not be displayed')
|
||||
def step(context, user, sync_folder):
|
||||
Toolbar.open_account(user)
|
||||
has_sync_connection = SyncConnection.has_sync_connection(sync_folder)
|
||||
with ensure(
|
||||
'There should not be "{0}" folder sync connection, but found.', sync_folder
|
||||
):
|
||||
has_sync_connection.should.be.false
|
||||
|
||||
|
||||
@When('the user navigates back in the sync connection wizard')
|
||||
def step(context):
|
||||
SyncConnectionWizard.back()
|
||||
|
||||
|
||||
@When('the user removes the folder sync connection')
|
||||
def step(context):
|
||||
SyncConnection.remove_folder_sync_connection()
|
||||
SyncConnection.confirm_folder_sync_connection_removal()
|
||||
|
||||
|
||||
@Then('the file "{file_name}" should have status "{status}" in the activity tab')
|
||||
def step(context, file_name, status):
|
||||
Activity.has_sync_status(file_name, status)
|
||||
|
||||
|
||||
@When('the user opens the sync connection wizard')
|
||||
def step(context):
|
||||
SyncConnectionWizard.open_sync_connection_wizard()
|
||||
|
||||
|
||||
@Then('the button to open sync connection wizard should be disabled')
|
||||
def step(context):
|
||||
test.compare(
|
||||
False,
|
||||
SyncConnectionWizard.is_add_sync_folder_button_enabled(),
|
||||
'Button to open sync connection wizard should be disabled',
|
||||
)
|
||||
|
||||
|
||||
@When('the user checks the activities of account "{account}"')
|
||||
def step(context, account):
|
||||
account = substitute_inline_codes(account)
|
||||
Activity.select_synced_filter(account)
|
||||
|
||||
|
||||
@Then('the following activities should be displayed in synced table')
|
||||
def step(context):
|
||||
activities = table_hashes(context.table)
|
||||
for activity in activities:
|
||||
activity["account"] = substitute_inline_codes(activity["account"])
|
||||
has_activity = Activity.has_activity(
|
||||
activity["resource"], activity["action"], activity["account"]
|
||||
)
|
||||
with ensure(
|
||||
'Activity should exist: {0} | {1} | {2}',
|
||||
activity["resource"],
|
||||
activity["action"],
|
||||
activity["account"],
|
||||
):
|
||||
has_activity.should.be.true
|
||||
|
||||
|
||||
@Then('the following activities should not be displayed in synced table')
|
||||
def step(context):
|
||||
activities = table_hashes(context.table)
|
||||
for activity in activities:
|
||||
activity["account"] = substitute_inline_codes(activity["account"])
|
||||
has_activity = Activity.has_activity(
|
||||
activity["resource"], activity["action"], activity["account"]
|
||||
)
|
||||
with ensure(
|
||||
'Activity should not exist: {0} | {1} | {2}',
|
||||
activity["resource"],
|
||||
activity["action"],
|
||||
activity["account"],
|
||||
):
|
||||
has_activity.should.be.false
|
||||
|
||||
|
||||
@Then(
|
||||
r'the following activities (should|should not) be displayed in not synced table',
|
||||
regexp=True,
|
||||
)
|
||||
def step(context, should_or_should_not):
|
||||
expected = should_or_should_not == "should"
|
||||
for row in context.table[1:]:
|
||||
resource = row[0]
|
||||
status = row[1]
|
||||
account = substitute_inline_codes(row[2])
|
||||
test.compare(
|
||||
Activity.check_not_synced_table(resource, status, account),
|
||||
expected,
|
||||
'Resource should be displayed in the not synced table',
|
||||
)
|
||||
|
||||
|
||||
@When('the user unchecks the "|any|" filter')
|
||||
def step(context, filter_option):
|
||||
Activity.select_not_synced_filter(filter_option)
|
||||
|
||||
|
||||
@Then('the following error message should appear in the client')
|
||||
def step(context):
|
||||
expected_error_message = '\n'.join(context.multiLineText)
|
||||
|
||||
actual_error_message = SyncConnection.get_permission_error_message()
|
||||
|
||||
# wait for error message to disappear
|
||||
SyncConnection.wait_for_error_label(False)
|
||||
|
||||
test.compare(
|
||||
actual_error_message,
|
||||
expected_error_message,
|
||||
f'Expected error message: "{expected_error_message}" but got: "{actual_error_message}"',
|
||||
)
|
||||
|
||||
|
||||
@Given('the user has waited for "|any|" seconds')
|
||||
def step(context, wait_for):
|
||||
squish.snooze(float(wait_for))
|
||||
|
||||
|
||||
@When(
|
||||
'the user unselects the following folders to sync in "Choose what to sync" window:'
|
||||
)
|
||||
def step(context):
|
||||
SyncConnection.choose_what_to_sync()
|
||||
folders = []
|
||||
for row in context.table:
|
||||
folders.append(row[0])
|
||||
SyncConnectionWizard.unselect_folders_to_sync(
|
||||
folders, new_sync_connection_wizard=False
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
from helpers.SetupClientHelper import get_resource_path
|
||||
from helpers.SyncHelper import perform_file_explorer_vfs_action
|
||||
from helpers.VFSFileHelper import is_placeholder_resource, is_file_downloaded
|
||||
|
||||
|
||||
@Then('the placeholder file "|any|" should exist on the file system')
|
||||
def step(context, file_name):
|
||||
resource_path = get_resource_path(file_name)
|
||||
test.compare(is_placeholder_resource(resource_path), True, f"File is a placeholder")
|
||||
|
||||
|
||||
@Then('the file "|any|" should be downloaded')
|
||||
def step(context, file_name):
|
||||
resource_path = get_resource_path(file_name)
|
||||
test.compare(is_file_downloaded(resource_path), True, f"File is downloaded")
|
||||
|
||||
|
||||
@When(r'user "([^"]*)" marks (?:file|folder) "([^"]*)" as "(Free up space|Always keep on this device)" from the file explorer', regexp=True)
|
||||
def step(context, user, resource, action):
|
||||
resource_path = get_resource_path(resource, user)
|
||||
perform_file_explorer_vfs_action(resource_path, action)
|
||||
Reference in New Issue
Block a user