# -*- coding: utf-8 -*- import names import os import sys from os import listdir from os.path import isfile, join, isdir import re import urllib.request import json import requests import shutil from objectmaphelper import RegularExpression from pageObjects.AccountConnectionWizard import AccountConnectionWizard from helpers.SetupClientHelper import * from helpers.FilesHelper import buildConflictedRegex from pageObjects.EnterPassword import EnterPassword from pageObjects.PublicLinkDialog import PublicLinkDialog from pageObjects.SharingDialog import SharingDialog from pageObjects.SyncWizard import SyncWizard from pageObjects.Toolbar import Toolbar from pageObjects.Activity import Activity from pageObjects.AccountStatus import AccountStatus # the script needs to use the system wide python # to switch from the built-in interpreter see https://kb.froglogic.com/squish/howto/using-external-python-interpreter-squish-6-6/ # if the IDE fails to reference the script, add the folder in Edit->Preferences->PyDev->Interpreters->Libraries sys.path.append(os.path.realpath('../../../shell_integration/nautilus/')) import syncstate import functools confdir = '/tmp/bdd-tests-owncloud-client/' confFilePath = confdir + 'owncloud.cfg' socketConnect = None stateDataFromMiddleware = None def getTestStateFromMiddleware(context): global stateDataFromMiddleware if stateDataFromMiddleware is None: res = requests.get( os.path.join(context.userData['middlewareUrl'], 'state'), headers={"Content-Type": "application/json"}, ) try: stateDataFromMiddleware = res.json() except ValueError: raise Exception("Could not get created users information from middleware") return stateDataFromMiddleware @OnScenarioStart def hook(context): try: os.makedirs(confdir, 0o0755) except: pass try: os.remove(confFilePath) except: pass @Given(r'the user has added (the first|another) account with', regexp=True) def step(context, accountType): newAccount = AccountConnectionWizard() if accountType == 'another': toolbar = Toolbar() toolbar.clickAddAccount() newAccount.addAccount(context) @When('the user adds the following wrong user credentials:') def step(context): newAccount = AccountConnectionWizard() newAccount.addUserCreds(context) @Then('an account should be displayed with the displayname |any| and host |any|') def step(context, displayname, host): displayname = substituteInLineCodes(context, displayname) host = substituteInLineCodes(context, host) test.compare( str( waitForObjectExists( { "name": "settingsdialog_toolbutton_" + displayname + "@" + host, "type": "QToolButton", "visible": 1, } ).text ), displayname + "\n" + host, ) def getDisplaynameForUser(context, username): usersDataFromMiddleware = getTestStateFromMiddleware(context) return usersDataFromMiddleware['created_users'][username]['displayname'] def getPasswordForUser(context, username): usersDataFromMiddleware = getTestStateFromMiddleware(context) return usersDataFromMiddleware['created_users'][username]['password'] @Given('user "|any|" has set up a client with default settings') def step(context, username): password = getPasswordForUser(context, username) displayName = getDisplaynameForUser(context, username) setUpClient(context, username, displayName, confFilePath) enterUserPassword = EnterPassword() enterUserPassword.enterPassword(password) @Given('the user has started the client') def step(context): startClient(context) @When(r'the user adds (the first|another) account with', regexp=True) def step(context, accountType): newAccount = AccountConnectionWizard() if accountType == 'another': toolbar = Toolbar() toolbar.clickAddAccount() newAccount.addAccount(context) @Given('the user has added the following account information:') def step(context): newAccount = AccountConnectionWizard() newAccount.addServer(context) newAccount.addUserCreds(context) newAccount.selectSyncFolder(context) def isItemSynced(type, itemName): if type != 'FILE' and type != 'FOLDER': raise Exception("type must be 'FILE' or 'FOLDER'") socketConnect = syncstate.SocketConnect() socketConnect.sendCommand("RETRIEVE_" + type + "_STATUS:" + itemName + "\n") if not socketConnect.read_socket_data_with_timeout(0.1): return False for line in socketConnect.get_available_responses(): if line.startswith('STATUS:OK') and line.endswith(itemName): return True elif line.endswith(itemName): return False def isFolderSynced(folderName): return isItemSynced('FOLDER', folderName) def isFileSynced(fileName): return isItemSynced('FILE', fileName) def waitForFileToBeSynced(context, fileName): waitFor( lambda: isFileSynced( sanitizePath(context.userData['currentUserSyncPath'] + fileName) ), context.userData['clientSyncTimeout'] * 1000, ) def waitForFolderToBeSynced(context, folderName): waitFor( lambda: isFolderSynced( sanitizePath(context.userData['currentUserSyncPath'] + folderName) ), context.userData['clientSyncTimeout'] * 1000, ) def folderExists(folderPath, timeout=1000): return waitFor( lambda: isdir(sanitizePath(folderPath)), timeout, ) def fileExists(filePath, timeout=1000): return waitFor( lambda: isfile(sanitizePath(filePath)), timeout, ) def sanitizePath(path): return path.replace('//', '/') def shareResource(resource): socketConnect = syncstate.SocketConnect() socketConnect.sendCommand("SHARE:" + resource + "\n") if not socketConnect.read_socket_data_with_timeout(0.1): return False for line in socketConnect.get_available_responses(): if line.startswith('SHARE:OK') and line.endswith(resource): return True elif line.endswith(resource): return False def executeStepThroughMiddleware(context, step): body = {"step": step} if hasattr(context, "table"): body["table"] = context.table params = json.dumps(body).encode('utf8') req = urllib.request.Request( context.userData['middlewareUrl'] + 'execute', data=params, headers={"Content-Type": "application/json"}, method='POST', ) try: urllib.request.urlopen(req) except urllib.error.HTTPError as e: raise Exception( "Step execution through test middleware failed. Error: " + e.read().decode() ) @When( 'the user adds "|any|" as collaborator of resource "|any|" with permissions "|any|" using the client-UI' ) def step(context, receiver, resource, permissions): openSharingDialog(context, resource) shareItem = SharingDialog() shareItem.addCollaborator(receiver, permissions) shareItem.closeSharingDialog() @When('the user adds following collaborators of resource "|any|" using the client-UI') def step(context, resource): openSharingDialog(context, resource) shareItem = SharingDialog() # In the following loop we are trying to share resource with given permission to one user at a time given from the data table in the feature file for row in context.table[1:]: receiver = row[0] permissions = row[1] shareItem.addCollaborator(receiver, permissions) shareItem.closeSharingDialog() @When( 'the user selects "|any|" as collaborator of resource "|any|" using the client-UI' ) def step(context, receiver, resource): openSharingDialog(context, resource) shareItem = SharingDialog() shareItem.selectCollaborator(receiver) @When( 'the user adds group "|any|" as collaborator of resource "|any|" with permissions "|any|" using the client-UI' ) def step(context, receiver, resource, permissions): openSharingDialog(context, resource) shareItem = SharingDialog() shareItem.addCollaborator(receiver, permissions, True) shareItem.closeSharingDialog() @Then( 'user "|any|" should be listed in the collaborators list for file "|any|" with permissions "|any|" on the client-UI' ) def step(context, receiver, resource, permissions): collaboratorShouldBeListed(context, receiver, resource, permissions) @Then( 'group "|any|" should be listed in the collaborators list for file "|any|" with permissions "|any|" on the client-UI' ) def step(context, receiver, resource, permissions): receiver += " (group)" collaboratorShouldBeListed(context, receiver, resource, permissions) def collaboratorShouldBeListed( context, receiver, resource, permissions, receiverCount=0 ): resource = getResourcePath(context, resource) socketConnect = syncstate.SocketConnect() socketConnect.sendCommand("SHARE:" + resource + "\n") permissionsList = permissions.split(',') waitForObject( { "container": names.sharingDialogUG_scrollArea_QScrollArea, "name": "sharedWith", "type": "QLabel", "visible": 1, } ) # findAllObjects: This functionfinds and returns a list of object references identified by the symbolic or real (multi-property) name objectName. sharedWithObj = findAllObjects( { "container": names.sharingDialogUG_scrollArea_QScrollArea, "name": "sharedWith", "type": "QLabel", "visible": 1, } ) # we use sharedWithObj list from above while verifying if users are listed or not. # For this we need an index value i.e receiverCount # For 1st user in the list the index will be 0 which is receiverCount default value # For 2nd user in the list the index will be 1 and so on test.compare(str(sharedWithObj[receiverCount].text), receiver) test.compare( waitForObjectExists(names.scrollArea_permissionsEdit_QCheckBox).checked, ('edit' in permissionsList), ) test.compare( waitForObjectExists(names.scrollArea_permissionShare_QCheckBox).checked, ('share' in permissionsList), ) shareItem = SharingDialog() shareItem.closeSharingDialog() @When('the user waits for the files to sync') def step(context): waitForFolderToBeSynced(context, '/') @When('the user waits for file "|any|" to be synced') def step(context, fileName): waitForFileToBeSynced(context, fileName) @When('the user waits for folder "|any|" to be synced') def step(context, folderName): waitForFolderToBeSynced(context, folderName) @Given('the user has waited for file "|any|" to be synced') def step(context, fileName): waitForFileToBeSynced(context, fileName) @Given( 'user "|any|" has created a file "|any|" with the following content inside the sync folder' ) def step(context, username, filename): createFile(context, filename, username) @When( 'user "|any|" creates a file "|any|" with the following content inside the sync folder' ) def step(context, username, filename): createFile(context, filename, username) def createFile(context, filename, username=None): fileContent = "\n".join(context.multiLineText) syncPath = None if username: syncPath = getUserSyncPath(context, username) else: syncPath = context.userData['currentUserSyncPath'] f = open(join(syncPath, filename), "w") f.write(fileContent) f.close() @When('user "|any|" creates a folder "|any|" inside the sync folder') def step(context, username, foldername): createFolder(context, foldername, username) @Given('user "|any|" has created a folder "|any|" inside the sync folder') def step(context, username, foldername): createFolder(context, foldername, username) def createFolder(context, foldername, username=None): syncPath = None if username: syncPath = getUserSyncPath(context, username) else: syncPath = context.userData['currentUserSyncPath'] path = join(syncPath, foldername) os.makedirs(path) @When('the user copies the folder "|any|" to "|any|"') def step(context, sourceFolder, destinationFolder): source_dir = join(context.userData['currentUserSyncPath'], sourceFolder) destination_dir = join(context.userData['currentUserSyncPath'], destinationFolder) shutil.copytree(source_dir, destination_dir) @Given(r"^(.*) on the server (.*)$", regexp=True) def step(context, stepPart1, stepPart2): executeStepThroughMiddleware(context, "Given " + stepPart1 + " " + stepPart2) global usersDataFromMiddleware usersDataFromMiddleware = None @Given(r"^(.*) on the server$", regexp=True) def step(context, stepPart1): executeStepThroughMiddleware(context, "Given " + stepPart1) global usersDataFromMiddleware usersDataFromMiddleware = None @Then(r"^(.*) on the server (.*)$", regexp=True) def step(context, stepPart1, stepPart2): executeStepThroughMiddleware(context, "Then " + stepPart1 + " " + stepPart2) @Then(r"^(.*) on the server$", regexp=True) def step(context, stepPart1): executeStepThroughMiddleware(context, "Then " + stepPart1) @Then('the file "|any|" should exist on the file system with the following content') def step(context, filePath): expected = "\n".join(context.multiLineText) filePath = context.userData['currentUserSyncPath'] + filePath f = open(filePath, 'r') contents = f.read() test.compare( expected, contents, "file expected to exist with content " + expected + " but does not have the expected content", ) @Then(r'^the (file|folder) "([^"]*)" should exist on the file system$', regexp=True) def step(context, resourceType, resource): resourcePath = join(context.userData['currentUserSyncPath'], resource) resourceExists = False if resourceType == 'file': resourceExists = fileExists( resourcePath, context.userData['clientSyncTimeout'] * 1000 ) elif resourceType == 'folder': resourceExists = folderExists( resourcePath, context.userData['clientSyncTimeout'] * 1000 ) else: raise Exception("Unsupported resource type '" + resourceType + "'") test.compare( True, resourceExists, "Assert " + resourceType + " '" + resource + "' exists on the system", ) @Then(r'^the (file|folder) "([^"]*)" should not exist on the file system$', regexp=True) def step(context, resourceType, resource): resourcePath = join(context.userData['currentUserSyncPath'], resource) resourceExists = False if resourceType == 'file': resourceExists = fileExists(resourcePath, 1000) elif resourceType == 'folder': resourceExists = folderExists(resourcePath, 1000) else: raise Exception("Unsupported resource type '" + resourceType + "'") test.compare( False, resourceExists, "Assert " + resourceType + " '" + resource + "' doesn't exist on the system", ) @Given('the user has paused the file sync') def step(context): waitForFolderToBeSynced(context, '/') syncWizard = SyncWizard() syncWizard.performAction("Pause sync") @Given('the user has changed the content of local file "|any|" to:') def step(context, filename): fileContent = "\n".join(context.multiLineText) f = open(context.userData['currentUserSyncPath'] + filename, "w") f.write(fileContent) f.close() @When('the user resumes the file sync on the client') def step(context): syncWizard = SyncWizard() syncWizard.performAction("Resume sync") @When('the user triggers force sync on the client') def step(context): mouseClick( waitForObjectItem(names.stack_folderList_QTreeView, "_1"), 720, 36, Qt.NoModifier, Qt.LeftButton, ) activateItem(waitForObjectItem(names.settings_QMenu, "Force sync now")) @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) namepart = filename.split('.')[0] extpart = filename.split('.')[1] onlyfiles = [ f for f in listdir(context.userData['currentUserSyncPath']) if isfile(join(context.userData['currentUserSyncPath'], f)) ] found = False pattern = re.compile(buildConflictedRegex(filename)) for file in onlyfiles: if pattern.match(file): f = open(context.userData['currentUserSyncPath'] + file, 'r') contents = f.read() if contents == expected: found = True break if not found: raise Exception("Conflict file not found with given name") @When('the user clicks on the activity tab') def step(context): toolbar = Toolbar() toolbar.clickActivity() @Then('a conflict warning should be shown for |integer| files') def step(context, files): clickTab(waitForObject(names.stack_QTabWidget), "Not Synced ({})".format(files)) test.compare( waitForObjectExists( names.oCC_IssuesWidget_treeWidget_QTreeWidget ).topLevelItemCount, files, ) test.compare( waitForObjectExists(names.oCC_IssuesWidget_treeWidget_QTreeWidget).visible, True ) test.compare( waitForObjectExists( names.o_treeWidget_Conflict_Server_version_downloaded_local_copy_renamed_and_not_uploaded_QModelIndex ).displayText, "Conflict: Server version downloaded, local copy renamed and not uploaded.", ) @Then('the table of conflict warnings should include file "|any|"') def step(context, filename): activity = Activity() activity.checkFileExist(filename) @Then('the file "|any|" should be blacklisted') def step(context, filename): activity = Activity() activity.checkBlackListedFileExist(filename) @When('the user selects "|any|" tab in the activity') def step(context, tabName): activity = Activity() activity.clickTab(tabName) def openSharingDialog(context, resource, itemType='file'): resource = getResourcePath(context, resource) if itemType == 'folder': waitFor( lambda: isFolderSynced(resource), context.userData['clientSyncTimeout'] * 1000, ) elif itemType == 'file': waitFor( lambda: isFileSynced(resource), context.userData['clientSyncTimeout'] * 1000 ) else: raise Exception("No such item type for resource") waitFor( lambda: shareResource(resource), context.userData['clientSyncTimeout'] * 1000 ) @When('the user opens the public links dialog of "|any|" using the client-UI') def step(context, resource): openSharingDialog(context, resource) publicLinkDialog = PublicLinkDialog() publicLinkDialog.openPublicLinkDialog() @When("the user toggles the password protection using the client-UI") def step(context): publicLinkDialog = PublicLinkDialog() publicLinkDialog.togglePassword() @Then('the password progress indicator should not be visible in the client-UI') def step(context): waitFor(lambda: (test.vp("publicLinkPasswordProgressIndicatorInvisible"))) @Then( 'the password progress indicator should not be visible in the client-UI - expected to fail' ) def step(context): waitFor(lambda: (test.xvp("publicLinkPasswordProgressIndicatorInvisible"))) @When('the user opens the sharing dialog of "|any|" using the client-UI') def step(context, resource): openSharingDialog(context, resource, 'folder') def getSharingDialogText(): shareItem = SharingDialog() errorText = shareItem.getSharingDialogMessage() return errorText @Then('the text "|any|" should be displayed in the sharing dialog') def step(context, fileShareContext): errorText = getSharingDialogText() test.compare( errorText, fileShareContext, ) @Then('the error text "|any|" should be displayed in the sharing dialog') def step(context, fileShareContext): errorText = getSharingDialogText() test.compare( errorText, fileShareContext, ) def createPublicLinkShare( context, resource, password='', permissions='', expireDate='', name='' ): resource = getResourcePath(context, resource) openSharingDialog(context, resource) publicLinkDialog = PublicLinkDialog() publicLinkDialog.openPublicLinkDialog() publicLinkDialog.createPublicLink( context, resource, password, permissions, expireDate, name ) @When( 'the user creates a new public link for file "|any|" without password using the client-UI' ) def step(context, resource): createPublicLinkShare(context, resource) @When( 'the user creates a new public link for file "|any|" with password "|any|" using the client-UI' ) def step(context, resource, password): createPublicLinkShare(context, resource, password) def setExpirationDateWithVerification(resource, publicLinkName, expireDate): publicLinkDialog = PublicLinkDialog() publicLinkDialog.verifyResource(resource) publicLinkDialog.verifyPublicLinkName(publicLinkName) publicLinkDialog.setExpirationDate(expireDate) @When('the user edits the public link named "|any|" of file "|any|" changing following') def step(context, publicLinkName, resource): expireDate = '' for row in context.table: if row[0] == 'expireDate': expireDate = row[1] break setExpirationDateWithVerification(resource, publicLinkName, expireDate) @When( 'the user creates a new public link with permissions "|any|" for folder "|any|" without password using the client-UI' ) def step(context, permissions, resource): createPublicLinkShare(context, resource, '', permissions) @When( 'the user creates a new public link with permissions "|any|" for folder "|any|" with password "|any|" using the client-UI' ) def step(context, permissions, resource, password): createPublicLinkShare(context, resource, password, permissions) @When('the user creates a new public link with following settings using the client-UI:') def step(context): linkSettings = {} for row in context.table: linkSettings[row[0]] = row[1] createPublicLinkShare( context, resource=linkSettings['path'], password=linkSettings['password'], expireDate=linkSettings['expireDate'], ) def createPublicShareWithRole(context, resource, role): resource = sanitizePath(substituteInLineCodes(context, resource)) openSharingDialog(context, resource) publicLinkDialog = PublicLinkDialog() publicLinkDialog.openPublicLinkDialog() publicLinkDialog.createPublicLinkWithRole(role) @When( 'the user creates a new public link for folder "|any|" using the client-UI with these details:' ) def step(context, resource): role = '' for row in context.table: if row[0] == 'role': role = row[1] break if role == '': raise Exception("No role has been found") else: createPublicShareWithRole(context, resource, role) @When('the user logs out of the client-UI') def step(context): accountStatus = AccountStatus() accountStatus.accountAction("Log out") def isUserSignedOut(context, username): displayname = getDisplaynameForUser(context, username) server = context.userData['localBackendUrl'] accountStatus = AccountStatus() test.compare( str(waitForObjectExists(accountStatus.SIGNED_OUT_TEXT_BAR).text), 'Signed out from ' + server + ' as ' + displayname + '.', ) def isUserSignedIn(context, username): displayname = getDisplaynameForUser(context, username) server = context.userData['localBackendUrl'] accountStatus = AccountStatus() test.compare( str(waitForObjectExists(accountStatus.SIGNED_OUT_TEXT_BAR).text), 'Connected ' + 'to ' + server + ' as ' + displayname + '.', ) @Then('user "|any|" should be signed out') def step(context, username): isUserSignedOut(context, username) @Given('user "|any|" has logged out of the client-UI') def step(context, username): waitForFolderToBeSynced(context, '/') # TODO: find some way to dynamically to check if files are synced # It might take some time for all files to sync snooze(5) accountStatus = AccountStatus() accountStatus.accountAction("Log out") isUserSignedOut(context, username) @When('user "|any|" logs in to the client-UI') def step(context, username): accountStatus = AccountStatus() accountStatus.accountAction("Log in") password = getPasswordForUser(context, username) enterUserPassword = EnterPassword() enterUserPassword.enterPassword(password) @Then('user "|any|" should be connect to the client-UI') def step(context, username): # TODO: find some way to dynamically to check if files are synced # It might take some time for all files to sync and connect to ther server snooze(5) isUserSignedIn(context, username) @When('the user removes the connection for user "|any|" and host |any|') def step(context, username, host): displayname = getDisplaynameForUser(context, username) displayname = substituteInLineCodes(context, displayname) host = substituteInLineCodes(context, host) clickButton( waitForObject( { "name": "settingsdialog_toolbutton_" + displayname + "@" + host, "type": "QToolButton", "visible": 1, } ) ) waitForFolderToBeSynced(context, '/') accountStatus = AccountStatus() accountStatus.removeConnection() @Then('an account with the displayname |any| and host |any| should not be displayed') def step(context, displayname, host): displayname = substituteInLineCodes(context, displayname) host = substituteInLineCodes(context, host) toolbar = Toolbar() displayedAccountText = toolbar.getDisplayedAccountText(displayname, host) test.compare( displayedAccountText, displayname + "\n" + host, ) @Then('connection wizard should be visible') def step(context): test.compare( str(waitForObjectExists(names.owncloudWizard_label_2_QLabel).text), 'Ser&ver Address', ) waitForObject(AccountConnectionWizard.SERVER_ADDRESS_BOX) @Then("the following tabs in the toolbar should match the default baseline") def step(context): for tabName in context.table: test.vp(tabName[0]) @When( 'the user removes permissions "|any|" for user "|any|" of resource "|any|" using the client-UI' ) def step(context, permissions, receiver, resource): openSharingDialog(context, resource) test.compare( str(waitForObjectExists(names.scrollArea_sharedWith_QLabel).text), receiver ) shareItem = SharingDialog() shareItem.removePermissions(permissions) @When("the user closes the sharing dialog") def step(context): clickButton(waitForObject(names.sharingDialog_Close_QPushButton)) @Then( '"|any|" permissions should not be displayed for user "|any|" for resource "|any|" on the client-UI' ) def step(context, permissions, user, resource): permissionsList = permissions.split(',') shareItem = SharingDialog() shareItem.verifyResource(resource) editChecked, shareChecked = shareItem.getAvailablePermission() if 'edit' in permissionsList: test.compare(editChecked, False) if 'share' in permissionsList: test.compare(shareChecked, False) @Then('the error "|any|" should be displayed') def step(context, errorMessage): sharingDialog = SharingDialog() test.compare(sharingDialog.getErrorText(), errorMessage) @When( 'the user tires to share resource "|any|" with the group "|any|" using the client-UI' ) def step(context, resource, group): openSharingDialog(context, resource) sharingDialog = SharingDialog() sharingDialog.selectCollaborator(group, True) @When('the user overwrites the file "|any|" with content "|any|"') def step(context, resource, content): print("starting file overwrite") waitForFileToBeSynced(context, resource) waitForFolderToBeSynced(context, '/') # overwriting the file immediately after it has been synced from the server seems to have some problem. # The client does not see the change although the changes have already been made thus we are having a race condition # So for now we add 5sec static wait # an issue https://github.com/owncloud/client/issues/8832 has been created for it snooze(5) f = open(context.userData['currentUserSyncPath'] + resource, "w") f.write(content) f.close() print("file has been overwritten") waitForFileToBeSynced(context, resource) @When('the user tries to overwrite the file "|any|" with content "|any|"') def step(context, resource, content): waitForFileToBeSynced(context, resource) waitForFolderToBeSynced(context, '/') try: f = open(context.userData['currentUserSyncPath'] + resource, "w") f.write(content) f.close() except: pass waitForFileToBeSynced(context, resource) def enableVFSSupport(vfsBtnText): # The enabling/disabling VFS button do not have it's own object # But it is inside the "stack_folderList_QTreeView" object. # So we are clicking at (718, 27) of "stack_folderList_QTreeView" object to enable/disable VFS mouseClick( waitForObjectItem(names.stack_folderList_QTreeView, "_1"), 718, 27, Qt.NoModifier, Qt.LeftButton, ) activateItem(waitForObjectItem(names.settings_QMenu, vfsBtnText)) clickButton( waitForObject(names.stack_Enable_experimental_placeholder_mode_QPushButton) ) @When("the user enables virtual file support") def step(context): enableVFSSupport("Enable virtual file support (experimental)...") @When('the user accepts the certificate') def step(context): clickButton(waitForObject(names.oCC_SslErrorDialog_cbTrustConnect_QCheckBox)) clickButton(waitForObject(names.oCC_SslErrorDialog_OK_QPushButton)) @Then('the lock shown should be closed') def step(context): test.vp("urlLock") @Then('error "|any|" should be displayed') def step(context, errorMsg): newAccount = AccountConnectionWizard() test.compare(str(waitForObjectExists(newAccount.ERROR_LABEL).text), errorMsg) @When(r'the user deletes the (file|folder) "([^"]*)"', regexp=True) def step(context, itemType, resource): resourcePath = sanitizePath(context.userData['currentUserSyncPath'] + resource) if itemType == 'file': os.remove(resourcePath) elif itemType == 'folder': shutil.rmtree(resourcePath) else: raise Exception("No such item type for resource") @When( 'the user unshares the resource "|any|" for collaborator "|any|" using the client-UI' ) def step(context, resource, receiver): openSharingDialog(context, resource) test.compare( str(waitForObjectExists(names.scrollArea_sharedWith_QLabel).text), receiver ) clickButton(waitForObject(names.scrollArea_deleteShareButton_QToolButton)) @Given('the user has added the following server address:') def step(context): newAccount = AccountConnectionWizard() newAccount.addServer(context) test.compare( waitForObjectExists(newAccount.CREDENTIAL_PAGE).visible, True, "Assert credentials page is visible", ) @When('the user adds the following server address:') def step(context): newAccount = AccountConnectionWizard() newAccount.addServer(context) @Given('the user has added the following user credentials:') def step(context): newAccount = AccountConnectionWizard() newAccount.addUserCreds(context) test.compare( waitForObjectExists(newAccount.ADVANCE_SETUP_PAGE).visible, True, "Assert setup page is visible", ) @Given('the user has opened chose_what_to_sync dialog') def step(context): newAccount = AccountConnectionWizard() newAccount.openSyncDialog() test.compare( waitForObjectExists(newAccount.SELECTIVE_SYNC_DIALOG).visible, True, "Assert selective sync dialog is visible", ) @When('the user opens chose_what_to_sync dialog') def step(context): newAccount = AccountConnectionWizard() newAccount.openSyncDialog() @When('the user selects the following folders to sync:') def step(context): newAccount = AccountConnectionWizard() newAccount.selectFoldersToSync(context) @When('the user selects manual sync folder option') def step(context): newAccount = AccountConnectionWizard() newAccount.selectManualSyncFolder() @When('the user connects the account') def step(context): newAccount = AccountConnectionWizard() newAccount.connectAccount() @When('the user sorts the folder list by "|any|"') def step(context, headerText): headerText = headerText.capitalize() if headerText in ["Size", "Name"]: newAccount = AccountConnectionWizard() newAccount.sortBy(headerText) else: raise Exception("Sorting by '" + headerText + "' is not supported.") @Then('the dialog chose_what_to_sync should be visible') def step(context): newAccount = AccountConnectionWizard() test.compare( waitForObjectExists(newAccount.SELECTIVE_SYNC_DIALOG).visible, True, "Assert selective sync dialog is visible", ) @Then('the sync all checkbox should be checked') def step(context): newAccount = AccountConnectionWizard() test.compare( waitForObjectExists(newAccount.SYNC_DIALOG_ROOT_FOLDER).checkState, "checked", "Assert sync all checkbox is checked", ) @Then("the folders should be in the following order:") def step(context): newAccount = AccountConnectionWizard() rowIndex = 0 for row in context.table[1:]: FOLDER_TREE_ROW = { "row": rowIndex, "container": newAccount.SYNC_DIALOG_ROOT_FOLDER, "type": "QModelIndex", } expectedFolder = row[0] actualFolder = waitForObjectExists(FOLDER_TREE_ROW).displayText test.compare(actualFolder, expectedFolder) rowIndex += 1 @When('the user deletes the public link for file "|any|"') def step(context, resource): openSharingDialog(context, resource) publicLinkDialog = PublicLinkDialog() publicLinkDialog.openPublicLinkDialog() test.compare( str(waitForObjectExists(publicLinkDialog.ITEM_TO_SHARE).text), resource.replace(context.userData['currentUserSyncPath'], ''), ) clickButton(waitForObject(names.linkShares_QToolButton_2)) clickButton(waitForObject(names.oCC_ShareLinkWidget_Delete_QPushButton)) @When( 'the user changes the password of public link "|any|" to "|any|" using the client-UI' ) def step(context, publicLinkName, password): publicLinkDialog = PublicLinkDialog() publicLinkDialog.verifyPublicLinkName(publicLinkName) publicLinkDialog.changePassword(password) @Then( 'the following users should be listed in as collaborators for file "|any|" on the client-UI' ) def step(context, resource): # Here we are trying to verify if the user added in when step are listed in the client-UI or not # We now have a variable name receiverCount which is used in collaboratorShouldBeListed function call receiverCount = 0 for row in context.table[1:]: receiver = row[0] permissions = row[1] collaboratorShouldBeListed( context, receiver, resource, permissions, receiverCount ) receiverCount += 1 def searchCollaborator(collaborator): shareItem = SharingDialog() shareItem.searchCollaborator(collaborator) @When('the user searches for collaborator "|any|" using the client-UI') def step(context, collaborator): searchCollaborator(collaborator) @When( 'the user searches for collaborator with autocomplete characters "|any|" using the client-UI' ) def step(context, collaborator): searchCollaborator(collaborator) @Then('the following users should be listed as suggested collaborators:') def step(context): shareItem = SharingDialog() for collaborator in context.table[1:]: exists = False try: waitForObjectItem(shareItem.SUGGESTED_COLLABORATOR, collaborator[0]) exists = True except LookupError as e: pass test.compare(exists, True, "Assert user '" + collaborator[0] + "' is listed") @Then('the collaborators should be listed in the following order:') def step(context): shareItem = SharingDialog() for index, collaborator in enumerate(context.table[1:], start=1): test.compare( str( waitForObjectExists( { "container": names.sharingDialogUG_scrollArea_QScrollArea, "name": "sharedWith", "occurrence": index, "type": "QLabel", "visible": 1, } ).text ), collaborator[0], ) @Then("VFS enabled baseline image should match the default screenshot") def step(context): test.vp("VP_VFS_enabled") @Then("VFS enabled baseline image should not match the default screenshot") def step(context): test.xvp("VP_VFS_enabled")