Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .woodpecker/cache-python.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ steps:
- . ./.woodpecker.env
- if $BROWSER_CACHE_FOUND; then exit 0; fi
- cd test/gui/
- python3 -m venv .venv --system-site-packages
- . .venv/bin/activate
- grep "^playwright" requirements.txt | pip install -r /dev/stdin
- make install-chromium
- tar -czf playwright-browsers.tar.gz .playwright

Expand Down
6 changes: 3 additions & 3 deletions test/gui/features/activity/activity.feature
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Feature: filter activity for user
| users |
| Alice |
| Brian |
When the user clicks on the activity tab
When the user opens the activity tab
And the user selects "Local Activity" tab in the activity
And the user checks the activities of account "Alice Hansen@%local_server_hostname%"
Then the following activities should be displayed in synced table
Expand All @@ -32,7 +32,7 @@ Feature: filter activity for user
| files |
| /.htaccess |
| /Folder1/a\\a.txt |
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the file "Folder1/a\\a.txt" should be blacklisted
And the file ".htaccess" should be excluded
Expand All @@ -48,7 +48,7 @@ Feature: filter activity for user
When user "Alice" creates the following files inside the sync folder:
| files |
| /.htaccess |
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the file ".htaccess" should be excluded
When the user unchecks the "Excluded" filter
Expand Down
2 changes: 1 addition & 1 deletion test/gui/features/spaces/spaces.feature
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Feature: Project spaces
"""
simple-folder: Not allowed because you don't have permission to add subfolders to that folder
"""
When the user clicks on the activity tab
When the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the following activities should be displayed in not synced table
| resource | status | account |
Expand Down
10 changes: 5 additions & 5 deletions test/gui/features/sync-resources/syncResources.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Feature: Syncing files
test content
"""
And the user waits for file "lorem-for-upload.txt" to be synced
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Local Activity" tab in the activity
Then the file "lorem-for-upload.txt" should have status "Uploaded" in the activity tab
And as "Alice" the file "lorem-for-upload.txt" should have the content "test content" in the server
Expand Down Expand Up @@ -45,7 +45,7 @@ Feature: Syncing files
And user "Alice" has uploaded file with content "changed server content" to "/conflict.txt" in the server
And the user has waited for "5" seconds
When the user resumes the file sync on the client
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the table of conflict warnings should include file "conflict.txt"
And the file "conflict.txt" should exist on the file system with the following content
Expand Down Expand Up @@ -181,7 +181,7 @@ Feature: Syncing files
And user "Alice" has set up a client with default settings
When user "Alice" creates a folder "folder with space at end " inside the sync folder
And the user force syncs the files
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the file "trailing-space.txt " should be ignored
And the file "folder with space at end " should be ignored
Expand Down Expand Up @@ -274,7 +274,7 @@ Feature: Syncing files
"""
test content
"""
And the user clicks on the activity tab
And the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the file "Folder1/a\\a.txt" should exist on the file system
And the file "Folder1/a\\a.txt" should be blacklisted
Expand Down Expand Up @@ -527,7 +527,7 @@ Feature: Syncing files
"""
And as "Brian" folder "simple-folder/sub-folder" should not exist in the server
And as "Brian" file "simple-folder/simple.pdf" should not exist in the server
When the user clicks on the activity tab
When the user opens the activity tab
And the user selects "Not Synced" tab in the activity
Then the following activities should be displayed in not synced table
| resource | status | account |
Expand Down
Comment thread
saw-jan marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Feature: Visually check all tabs
I want to visually check all tabs in client
So that I can perform all the actions related to client


@smoke
Scenario: Tabs in toolbar looks correct
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests fails.
Am i doing something wrong?

  Scenario: Verify various setting options in Settings tab                          # features/tabs-settings/test.feature:17
    Given user "Alice" has been created in the server with default attributes       # steps/server_context.py:8 0.072s
    And user "Alice" has set up a client with default settings                      # steps/account_context.py:55
      Traceback (most recent call last):
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/behave/model.py", line 1991, in run
          match.run(runner.context)
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/behave/matchers.py", line 105, in run
          self.func(context, *args, **kwargs)
        File "steps/account_context.py", line 62, in step
          enter_password.login_after_setup(username, password)
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/pageObjects/EnterPassword.py", line 39, in login_after_setup
          self.oidc_relogin(username, password)
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/pageObjects/EnterPassword.py", line 33, in oidc_relogin
          authorize_via_webui(username, password)
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/helpers/WebUIHelper.py", line 12, in authorize_via_webui
          page.goto(url)
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/sync_api/_generated.py", line 9054, in goto
          self._sync(
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/_impl/_sync_base.py", line 115, in _sync
          return task.result()
                 ^^^^^^^^^^^^^
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/_impl/_page.py", line 552, in goto
          return await self._main_frame.goto(**locals_to_params(locals()))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/_impl/_frame.py", line 153, in goto
          await self._channel.send(
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 69, in send
          return await self._connection.wrap_api_call(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/prashant/Desktop/projects/oc-desktop/desktop/test/gui/venv/lib/python3.12/site-packages/playwright/_impl/_connection.py", line 559, in wrap_api_call
          raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None
      playwright._impl._errors.Error: Page.goto: Protocol error (Page.navigate): Cannot navigate to invalid URL
      Call log:
        - navigating to "Cannot navigate to invalid URL", waiting until "load"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

browser login failed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am also facing same issue

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, that's weird. Could you check your chromium version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or check with headed mode to see what happens:

browser = pw.chromium.launch(headless=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it accessible.
image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scenario is fine.

Scenario: Tabs in toolbar looks correct

But another one is failing:

Scenario: Verify various setting options in Settings tab                          # features/tabs-settings/tabsSettings.feature:17
    Given user "Alice" has been created in the server with default attributes       # steps/server_context.py:8 0.070s
    And user "Alice" has set up a client with default settings                      # steps/account_context.py:55
    And user "Alice" has set up a client with default settings                      # steps/account_context.py:55 2.801s
    When the user opens the settings tab                                            # steps/sync_context.py:86 0.217s
      ASSERT FAILED: Settings tab is not active

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be similar issue: #910 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct in this test case as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's see into this issue separately.

Given user "Alice" has been created in the server with default attributes
And user "Alice" has set up a client with default settings
Expand All @@ -13,19 +13,18 @@ Feature: Visually check all tabs
| Settings |
| Quit |


@smoke
Scenario: Verify various setting options in Settings tab
Given user "Alice" has been created in the server with default attributes
And user "Alice" has set up a client with default settings
When the user clicks on the settings tab
When the user opens the settings tab
Then the settings tab should have the following options in the general section:
| Start on Login |
And the settings tab should have the following options in the advanced section:
| Sync hidden files |
| Edit ignored files |
| Log settings |
And the settings tab should have the following options in the network section:
| Proxy Settings |
| Download Bandwidth |
| Upload Bandwidth |
When the user opens the about dialog
Expand Down
File renamed without changes.
85 changes: 65 additions & 20 deletions test/gui/pageObjects/Settings.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
from types import SimpleNamespace
from appium.webdriver.common.appiumby import AppiumBy as By

from helpers.AppHelper import app


class Settings:
CHECKBOX_OPTION_ITEM = SimpleNamespace(by=None, selector=None)
NETWORK_OPTION_ITEM = SimpleNamespace(by=None, selector=None)
ABOUT_BUTTON = SimpleNamespace(by=None, selector=None)
ABOUT_DIALOG = SimpleNamespace(by=None, selector=None)
ABOUT_DIALOG_OK_BUTTON = SimpleNamespace(by=None, selector=None)
GENERAL_OPTIONS_MAP = SimpleNamespace(by=None, selector=None)
ADVANCED_OPTION_MAP = SimpleNamespace(by=None, selector=None)
NETWORK_OPTION_MAP = SimpleNamespace(by=None, selector=None)
ABOUT_BUTTON = SimpleNamespace(by=By.NAME, selector="About")
ABOUT_DIALOG = SimpleNamespace(by=By.CLASS_NAME, selector="[page tab | About]")
ABOUT_DIALOG_OK_BUTTON = SimpleNamespace(by=By.NAME, selector="OK")
GENERAL_SETTING_START_ON_LOGIN = SimpleNamespace(
by=By.XPATH, selector="//panel/*[@name='Start on Login']"
)
GENERAL_SETTING_LANGUAGE = SimpleNamespace(
by=By.XPATH, selector="//panel/label[@name='Language']"
)
ADVANCED_SETTING_SYNC_HIDDEN_FILES = SimpleNamespace(
by=By.XPATH, selector="//panel/*[@name='Sync hidden files']"
)
ADVANCED_SETTING_EDIT_IGNORED_FILES = SimpleNamespace(
by=By.XPATH, selector="//panel/*[@name='Edit Ignored Files']"
)
ADVANCED_SETTING_LOG_SETTINGS = SimpleNamespace(
by=By.XPATH, selector="//panel/*[@name='Log Settings']"
)
NETWORK_SETTING_DOWNLOAD_BANDWIDTH = SimpleNamespace(
by=By.XPATH, selector="//panel[@name='Download Bandwidth']"
)
NETWORK_SETTING_UPLOAD_BANDWIDTH = SimpleNamespace(
by=By.XPATH, selector="//panel[@name='Upload Bandwidth']"
)

@staticmethod
def get_checkbox_option_selector(name):
Expand All @@ -29,28 +49,53 @@ def get_network_option_selector(name):
return selector

@staticmethod
def check_general_option(option):
selector = Settings.GENERAL_OPTIONS_MAP[option]
squish.waitForObjectExists(Settings.get_checkbox_option_selector(selector))
def has_general_setting(setting):
if setting.lower() == "start on login":
locator = Settings.GENERAL_SETTING_START_ON_LOGIN
elif setting.lower() == "language":
locator = Settings.GENERAL_SETTING_LANGUAGE
else:
raise ValueError(f"Unknown general setting: {setting}")
return app().find_element(locator.by, locator.selector).is_displayed()

@staticmethod
def check_advanced_option(option):
selector = Settings.ADVANCED_OPTION_MAP[option]
squish.waitForObjectExists(Settings.get_checkbox_option_selector(selector))
def has_advanced_setting(setting):
if setting.lower() == "sync hidden files":
locator = Settings.ADVANCED_SETTING_SYNC_HIDDEN_FILES
elif setting.lower() == "edit ignored files":
locator = Settings.ADVANCED_SETTING_EDIT_IGNORED_FILES
elif setting.lower() == "log settings":
locator = Settings.ADVANCED_SETTING_LOG_SETTINGS
else:
raise ValueError(f"Unknown advanced setting: {setting}")
return app().find_element(locator.by, locator.selector).is_displayed()

@staticmethod
def check_network_option(option):
selector = Settings.NETWORK_OPTION_MAP[option]
squish.waitForObjectExists(Settings.get_network_option_selector(selector))
def has_network_setting(setting):
if setting.lower() == "download bandwidth":
locator = Settings.NETWORK_SETTING_DOWNLOAD_BANDWIDTH
elif setting.lower() == "upload bandwidth":
locator = Settings.NETWORK_SETTING_UPLOAD_BANDWIDTH
else:
raise ValueError(f"Unknown network setting: {setting}")
return app().find_element(locator.by, locator.selector).is_displayed()

@staticmethod
def open_about_button():
squish.clickButton(squish.waitForObject(Settings.ABOUT_BUTTON))
def open_about_dialog():
app().find_element(
Settings.ABOUT_BUTTON.by, Settings.ABOUT_BUTTON.selector
).click()

@staticmethod
def wait_for_about_dialog_to_be_visible():
squish.waitForObjectExists(Settings.ABOUT_DIALOG)
def has_about_dialog():
return (
app()
.find_element(Settings.ABOUT_DIALOG.by, Settings.ABOUT_DIALOG.selector)
.is_displayed()
)

@staticmethod
def close_about_dialog():
squish.clickButton(squish.waitForObjectExists(Settings.ABOUT_DIALOG_OK_BUTTON))
app().find_element(
Settings.ABOUT_DIALOG_OK_BUTTON.by, Settings.ABOUT_DIALOG_OK_BUTTON.selector
).click()
46 changes: 28 additions & 18 deletions test/gui/pageObjects/Toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ class Toolbar:
NAVIGATION_BAR = SimpleNamespace(
by=By.XPATH, selector="//*[@name='Navigation bar']/.."
)
ACCOUNT_BUTTON = SimpleNamespace(by=By.CLASS_NAME, selector="[page tab | {text}]")
ACCOUNT_TAB = SimpleNamespace(by=By.CLASS_NAME, selector="[page tab | {text}]")
ADD_ACCOUNT_BUTTON = SimpleNamespace(
by=By.CLASS_NAME, selector="[push button | Add Account]"
)
ACTIVITY_BUTTON = SimpleNamespace(
by=By.CLASS_NAME, selector="[page tab | Activity]"
)
SETTINGS_BUTTON = SimpleNamespace(by=None, selector=None)
ACTIVITY_TAB = SimpleNamespace(by=By.CLASS_NAME, selector="[page tab | Activity]")
SETTINGS_TAB = SimpleNamespace(by=By.CLASS_NAME, selector="[page tab | Settings]")
QUIT_BUTTON = SimpleNamespace(by=By.CLASS_NAME, selector="[push button | Quit]")
CONFIRM_QUIT_BUTTON = SimpleNamespace(
by=By.NAME,
Expand Down Expand Up @@ -53,18 +51,22 @@ def get_item_selector(item_name):
}

@staticmethod
def has_item(item_name, timeout=get_config("minSyncTimeout") * 1000):
try:
squish.waitForObject(Toolbar.get_item_selector(item_name), timeout)
return True
except:
return False
def has_tab(tab_name):
if tab_name.lower() == "add account":
tab = Toolbar.ADD_ACCOUNT_BUTTON
elif tab_name.lower() == "activity":
tab = Toolbar.ACTIVITY_TAB
elif tab_name.lower() == "settings":
tab = Toolbar.SETTINGS_TAB
elif tab_name.lower() == "quit":
tab = Toolbar.QUIT_BUTTON
else:
raise ValueError(f"Unknown tab: {tab_name}")
return app().find_element(tab.by, tab.selector).is_displayed()

@staticmethod
def open_activity():
tab = app().find_element(
Toolbar.ACTIVITY_BUTTON.by, Toolbar.ACTIVITY_BUTTON.selector
)
tab = app().find_element(Toolbar.ACTIVITY_TAB.by, Toolbar.ACTIVITY_TAB.selector)
# ISSUE: https://github.com/opencloud-eu/desktop/pull/879
# Cannot select navigation tab by click event
# Select the navigation tab using keyboard events as a workaround
Expand Down Expand Up @@ -104,7 +106,15 @@ def get_displayed_account_text(displayname, host):

@staticmethod
def open_settings_tab():
squish.mouseClick(squish.waitForObject(Toolbar.SETTINGS_BUTTON))
tab = app().find_element(Toolbar.SETTINGS_TAB.by, Toolbar.SETTINGS_TAB.selector)
# ISSUE: https://github.com/opencloud-eu/desktop/pull/879
# Cannot select navigation tab by click event
# Select the navigation tab using keyboard events as a workaround
# TODO: Remove the workaround and uncomment 'click' action
# tab.click()
tab.native_click()
if tab.get_attribute("checked") != "true":
raise AssertionError("Settings tab is not active")

@staticmethod
def quit_opencloud():
Expand All @@ -127,7 +137,7 @@ def get_accounts():
"initials": str(obj.accountState.account.initials),
"current": obj.checked,
}
account_locator = Toolbar.ACCOUNT_BUTTON.copy()
account_locator = Toolbar.ACCOUNT_TAB.copy()
if account_idx > 1:
account_locator.update({"occurrence": account_idx})
account_locator.update({"text": account_info["hostname"]})
Expand All @@ -145,8 +155,8 @@ def get_account(username):
account = None
try:
account = app().find_element(
Toolbar.ACCOUNT_BUTTON.by,
Toolbar.ACCOUNT_BUTTON.selector.format(text=account_label),
Toolbar.ACCOUNT_TAB.by,
Toolbar.ACCOUNT_TAB.selector.format(text=account_label),
)
except NoSuchElementException:
pass
Expand Down
Loading
Loading