Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gui-tests][full-ci] Add multiple accounts in a single step #11324

Draft
wants to merge 3 commits into
base: 5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
132 changes: 76 additions & 56 deletions test/gui/shared/scripts/helpers/SetupClientHelper.py
@@ -1,10 +1,12 @@
from urllib.parse import urlparse
import squish
import uuid
from os import makedirs
from os.path import exists, join
from helpers.SpaceHelper import get_space_id
from helpers.ConfigHelper import get_config, set_config
from helpers.SyncHelper import listenSyncStatusForItem
from helpers.UserHelper import getDisplaynameForUser


def substituteInLineCodes(value):
Expand Down Expand Up @@ -90,65 +92,83 @@ def startClient():


def getPollingInterval():
pollingInterval = '''[ownCloud]
remotePollInterval={pollingInterval}
'''
pollingInterval = '''
[ownCloud]
remotePollInterval={pollingInterval}
'''
args = {'pollingInterval': 5000}
pollingInterval = pollingInterval.format(**args)
return pollingInterval


def setUpClient(username, displayName, space="Personal"):
userSetting = '''
[Accounts]
0/Folders/1/davUrl={url}
0/Folders/1/ignoreHiddenFiles=true
0/Folders/1/localPath={client_sync_path}
0/Folders/1/displayString={displayString}
0/Folders/1/paused=false
0/Folders/1/targetPath=/
0/Folders/1/version=2
0/Folders/1/virtualFilesMode=off
0/dav_user={davUserName}
0/display-name={displayUserName}
0/http_CredentialVersion=1
0/http_oauth={oauth}
0/http_user={davUserName}
0/url={local_server}
0/user={displayUserFirstName}
0/version=1
version=2
'''

userSetting = userSetting + getPollingInterval()

syncPath = createUserSyncPath(username)
dav_endpoint = join("remote.php/dav/files", username)

server_url = get_config('localBackendUrl')
is_ocis = get_config('ocis')
if is_ocis:
set_config('syncConnectionName', space)
syncPath = createSpacePath(space)
if space == "Personal":
space = displayName
dav_endpoint = join("dav/spaces", get_space_id(space, username))

args = {
'url': join(server_url, dav_endpoint, ''),
'displayString': get_config('syncConnectionName'),
'displayUserName': displayName,
'davUserName': username if is_ocis else username.lower(),
'displayUserFirstName': displayName.split()[0],
'client_sync_path': syncPath,
'local_server': server_url,
'oauth': 'true' if is_ocis else 'false',
}
userSetting = userSetting.format(**args)

configFile = open(get_config('clientConfigFile'), "w")
configFile.write(userSetting)
configFile.close()

def generate_account_config(users, space="Personal"):
sync_paths = []
user_setting = ''
for idx, username in enumerate(users):
user_setting += '''
{user_index}/Folders/{uuid_v4}/davUrl={url}
{user_index}/Folders/{uuid_v4}/ignoreHiddenFiles=true
{user_index}/Folders/{uuid_v4}/localPath={client_sync_path}
{user_index}/Folders/{uuid_v4}/displayString={displayString}
{user_index}/Folders/{uuid_v4}/paused=false
{user_index}/Folders/{uuid_v4}/targetPath=/
{user_index}/Folders/{uuid_v4}/version=13
{user_index}/Folders/{uuid_v4}/virtualFilesMode=off
{user_index}/dav_user={davUserName}
{user_index}/display-name={displayUserName}
{user_index}/http_CredentialVersion=1
{user_index}/http_oauth={oauth}
{user_index}/http_user={davUserName}
{user_index}/url={local_server}
{user_index}/user={displayUserFirstName}
{user_index}/version=13
'''

if not idx:
user_setting = "[Accounts]" + user_setting

sync_path = createUserSyncPath(username)
dav_endpoint = join("remote.php/dav/files", username)

server_url = get_config('localBackendUrl')
is_ocis = get_config('ocis')
if is_ocis:
set_config('syncConnectionName', space)
sync_path = createSpacePath(space)
if space == "Personal":
space = getDisplaynameForUser(username)
dav_endpoint = join("dav/spaces", get_space_id(space, username))

args = {
'url': join(server_url, dav_endpoint, ''),
'displayString': get_config('syncConnectionName'),
'displayUserName': getDisplaynameForUser(username),
'davUserName': username if is_ocis else username.lower(),
'displayUserFirstName': getDisplaynameForUser(username).split()[0],
'client_sync_path': sync_path,
'local_server': server_url,
'oauth': 'true' if is_ocis else 'false',
'user_index': idx,
'uuid_v4': generate_UUIDV4(),
}
user_setting = user_setting.format(**args)
sync_paths.append(sync_path)
# append extra configs
user_setting += "version=13"
user_setting = user_setting + getPollingInterval()

config_file = open(get_config('clientConfigFile'), "a+", encoding="utf-8")
config_file.write(user_setting)
config_file.close()

return sync_paths


def setUpClient(username, space="Personal"):
sync_path = generate_account_config([username], space)
startClient()
listenSyncStatusForItem(syncPath)
listenSyncStatusForItem(sync_path[0])


def generate_UUIDV4():
return str(uuid.uuid4())
95 changes: 71 additions & 24 deletions test/gui/shared/scripts/pageObjects/EnterPassword.py
Expand Up @@ -2,58 +2,105 @@
import squish
from helpers.WebUIHelper import authorize_via_webui
from helpers.ConfigHelper import get_config
from pageObjects.AccountConnectionWizard import AccountConnectionWizard
from helpers.UserHelper import getDisplaynameForUser, getPasswordForUser


class EnterPassword:
LOGIN_DIALOG = {
"name": "LoginRequiredDialog",
"type": "OCC::LoginRequiredDialog",
"visible": 1,
}
LOGIN_USER_LABEL = {
"name": "topLabel",
"type": "QLabel",
"visible": 1,
"window": LOGIN_DIALOG,
}
USERNAME_BOX = {
"name": "usernameLineEdit",
"type": "QLineEdit",
"visible": 1,
"window": LOGIN_DIALOG,
}
PASSWORD_BOX = {
"container": names.loginRequiredDialog_contentWidget_QStackedWidget,
"name": "passwordLineEdit",
"type": "QLineEdit",
"visible": 1,
"window": LOGIN_DIALOG,
}
LOGIN_BUTTON = {
"text": "Log in",
"type": "QPushButton",
"unnamed": 1,
"visible": 1,
"window": names.loginRequiredDialog_OCC_LoginRequiredDialog,
"window": LOGIN_DIALOG,
}
COPY_URL_TO_CLIPBOARD_BUTTON = {
"container": names.loginRequiredDialog_contentWidget_QStackedWidget,
"name": "copyUrlToClipboardButton",
"type": "QPushButton",
"visible": 1,
"window": LOGIN_DIALOG,
}
TLS_CERT_WINDOW = {
"name": "OCC__TlsErrorDialog",
"type": "OCC::TlsErrorDialog",
"visible": 1,
}
ACCEPT_CERTIFICATE_YES = {
"text": "Yes",
"type": "QPushButton",
"visible": 1,
"window": TLS_CERT_WINDOW,
}

@staticmethod
def enterPassword(password):
squish.waitForObject(
EnterPassword.PASSWORD_BOX, get_config('maxSyncTimeout') * 1000
def __init__(self, occurrence=1):
if occurrence > 1 and not get_config('ocis'):
self.LOGIN_DIALOG.update({"occurrence": occurrence})
elif occurrence > 1 and get_config('ocis'):
self.TLS_CERT_WINDOW.update({"occurrence": occurrence})

def get_username(self):
# Parse username from following label:
# Please enter your password to log in to the account Alice Hansen@localhost.
# The account Alice Hansen@localhost:9200 is currently logged out.
label = str(squish.waitForObjectExists(self.LOGIN_USER_LABEL).text)
label = label.split("@", maxsplit=1)[0].split(" ")
label.reverse()
return label[1].capitalize()

def enterPassword(self, password):
squish.waitForObjectExists(
self.PASSWORD_BOX, get_config('maxSyncTimeout') * 1000
)
squish.type(squish.waitForObject(EnterPassword.PASSWORD_BOX), password)
squish.clickButton(squish.waitForObject(EnterPassword.LOGIN_BUTTON))
squish.type(
squish.waitForObject(self.PASSWORD_BOX),
password,
)
squish.clickButton(squish.waitForObjectExists(self.LOGIN_BUTTON))

@staticmethod
def oidcReLogin(username, password):
def oidcReLogin(self, username, password):
# wait 500ms for copy button to fully load
squish.snooze(1 / 2)
squish.clickButton(
squish.waitForObject(EnterPassword.COPY_URL_TO_CLIPBOARD_BUTTON)
)
squish.clickButton(squish.waitForObject(self.COPY_URL_TO_CLIPBOARD_BUTTON))
authorize_via_webui(username, password)

@staticmethod
def reLogin(username, password):
def reLogin(self, username, password):
if get_config('ocis'):
EnterPassword.oidcReLogin(username, password)
self.oidcReLogin(username, password)
else:
EnterPassword.enterPassword(password)
self.enterPassword(password)

@staticmethod
def loginAfterSetup(username, password):
def loginAfterSetup(self, username=None, password=None):
if get_config('ocis'):
AccountConnectionWizard.acceptCertificate()
EnterPassword.oidcReLogin(username, password)
self.accept_certificate()
if not username:
username = self.get_username()
password = getPasswordForUser(username)
if get_config('ocis'):
self.oidcReLogin(username, password)
else:
EnterPassword.enterPassword(password)
self.enterPassword(password)

def accept_certificate(self):
squish.clickButton(squish.waitForObject(self.ACCEPT_CERTIFICATE_YES))
49 changes: 32 additions & 17 deletions test/gui/shared/steps/account_context.py
Expand Up @@ -4,22 +4,19 @@
from pageObjects.Toolbar import Toolbar
from pageObjects.AccountSetting import AccountSetting

from helpers.SetupClientHelper import substituteInLineCodes, getClientDetails
from helpers.SetupClientHelper import (
setUpClient,
startClient,
substituteInLineCodes,
getClientDetails,
generate_account_config,
getResourcePath,
)
from helpers.UserHelper import getDisplaynameForUser, getPasswordForUser
from helpers.SetupClientHelper import setUpClient, startClient
from helpers.SyncHelper import waitForInitialSyncToComplete
from helpers.SetupClientHelper import getResourcePath
from helpers.SyncHelper import waitForInitialSyncToComplete, listenSyncStatusForItem
from helpers.ConfigHelper import get_config


@Given(r'the user has added (the first|another) account with', regexp=True)
def step(context, accountType):
if accountType == 'another':
Toolbar.openNewAccountSetup()
account_details = getClientDetails(context)
AccountConnectionWizard.addAccount(account_details)


@When('the user adds the following wrong user credentials:')
def step(context):
account_details = getClientDetails(context)
Expand Down Expand Up @@ -52,14 +49,30 @@ def step(context, displayname, host):
@Given('user "|any|" has set up a client with default settings')
def step(context, username):
password = getPasswordForUser(username)
displayName = getDisplaynameForUser(username)
setUpClient(username, displayName)
EnterPassword.loginAfterSetup(username, password)
setUpClient(username)
enter_password = EnterPassword()
enter_password.loginAfterSetup(username, password)

# wait for files to sync
waitForInitialSyncToComplete(getResourcePath('/', username))


@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)
startClient()
for idx, sync_path in enumerate(sync_paths):
listenSyncStatusForItem(sync_path)
# login from last dialog
enter_password = EnterPassword(len(sync_paths) - idx)
enter_password.loginAfterSetup()
# wait for files to sync
waitForInitialSyncToComplete(sync_path)


@Given('the user has started the client')
def step(context):
startClient()
Expand Down Expand Up @@ -111,7 +124,8 @@ def step(context, username):
def step(context, username):
AccountSetting.login()
password = getPasswordForUser(username)
EnterPassword.reLogin(username, password)
enter_password = EnterPassword()
enter_password.reLogin(username, password)

# wait for files to sync
waitForInitialSyncToComplete(getResourcePath('/', username))
Expand All @@ -124,7 +138,8 @@ def step(context, username):

@When('user "|any|" enters the password "|any|"')
def step(context, username, password):
EnterPassword.reLogin(username, password)
enter_password = EnterPassword()
enter_password.reLogin(username, password)


@Then('user "|any|" should be connect to the client-UI')
Expand Down
6 changes: 3 additions & 3 deletions test/gui/shared/steps/spaces_context.py
Expand Up @@ -38,9 +38,9 @@ def step(context, user, space_name, role):
@Given('user "|any|" has set up a client with space "|any|"')
def step(context, user, space_name):
password = getPasswordForUser(user)
displayName = getDisplaynameForUser(user)
setUpClient(user, displayName, space_name)
EnterPassword.loginAfterSetup(user, password)
setUpClient(user, space_name)
enter_password = EnterPassword()
enter_password.loginAfterSetup(user, password)
# wait for files to sync
waitForInitialSyncToComplete(getResourcePath('/', user, space_name))

Expand Down
8 changes: 3 additions & 5 deletions test/gui/tst_removeAccountConnection/test.feature
Expand Up @@ -8,11 +8,9 @@ Feature: remove account connection
Scenario: remove an account connection
Given user "Alice" has been created on the server with default attributes and without skeleton files
And user "Brian" has been created on the server with default attributes and without skeleton files
And user "Alice" has set up a client with default settings
And the user has added another account with
| server | %local_server% |
| user | Brian |
| password | AaBb2Cc3Dd4 |
And the user has set up the following accounts with default settings:
| Alice |
| Brian |
When the user removes the connection for user "Brian" and host %local_server_hostname%
Then the account with displayname "Brian Murphy" and host "%local_server_hostname%" should not be displayed
But the account with displayname "Alice Hansen" and host "%local_server_hostname%" should be displayed
Expand Down