Skip to content

Commit 4107aa0

Browse files
authored
Bc/private downloads (#142)
* beginning of test * beginning of test * add toolbar check * almost there, context menu won't close * close the context menu * close the context menu * close the context menu * actually check downloads context menu options * delete files after test * fix download remover * check geckodriver version * doorhanger test unstable * remove alert function - it's not good * fix bad window switch * screenshot non-empty downloads * stop failing on about:downloads not empty, but log
1 parent 7f44c0b commit 4107aa0

14 files changed

+344
-6
lines changed

collect_executables.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ do
105105
sleep 0.2
106106
done
107107
chmod +x geckodriver
108+
./geckodriver --version
108109

109110
if [[ $SYSTEM_NAME == "linux" ]]
110111
then

modules/browser_object.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from modules.browser_object_about_downloads_context_menu import *
12
from modules.browser_object_about_prefs_cc_popup import *
23
from modules.browser_object_autofill_popup import *
34
from modules.browser_object_credit_card_popup import *
@@ -10,4 +11,5 @@
1011
from modules.browser_object_search_bar_context_menu import *
1112
from modules.browser_object_tab_context_menu import *
1213
from modules.browser_object_tabbar import *
14+
from modules.browser_object_toolbar import *
1315
from modules.browser_object_tracker_panel import *
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import logging
2+
3+
from modules.browser_object_context_menu import ContextMenu
4+
5+
6+
class AboutDownloadsContextMenu(ContextMenu):
7+
"""
8+
Browser object model for the context menu for right clicking a download in About:Downloads
9+
"""
10+
11+
def has_all_options_available(self) -> ContextMenu:
12+
"""Timeout unless all items labeled downloadOption are present, else return self"""
13+
with self.driver.context(self.context_id):
14+
for elname in [
15+
k for k, v in self.elements.items() if "downloadOption" in v["groups"]
16+
]:
17+
logging.info(f"elname {elname}")
18+
self.element_exists(elname)
19+
return self

modules/browser_object_toolbar.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from time import sleep
2+
3+
from selenium.webdriver.support import expected_conditions as EC
4+
5+
from modules.page_base import BasePage
6+
7+
8+
class Toolbar(BasePage):
9+
"""BOM for the toolbar, other than the awesome bar and the panel UI"""
10+
11+
URL_TEMPLATE = ""
12+
13+
def wait_for_item_to_download(self, filename: str) -> BasePage:
14+
"""Check the downloads tool in the toolbar to wait for a given file to download"""
15+
original_timeout = self.driver.timeouts.implicit_wait
16+
try:
17+
# Whatever our timeout, we want to lengthen it because downloads
18+
self.driver.implicitly_wait(original_timeout * 2)
19+
self.element_visible("downloads-item-by-file", labels=[filename])
20+
self.expect_not(
21+
EC.element_attribute_to_include(
22+
self.get_selector("downloads-button"), "animate"
23+
)
24+
)
25+
with self.driver.context(self.context_id):
26+
self.driver.execute_script(
27+
"arguments[0].setAttribute('hidden', true)",
28+
self.get_element("downloads-button"),
29+
)
30+
finally:
31+
self.driver.implicitly_wait(original_timeout)
32+
33+
return self
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"no-downloads-label": {
3+
"selectorData": "downloadsListEmptyDescription",
4+
"strategy": "id",
5+
"groups": []
6+
},
7+
8+
"download-target": {
9+
"selectorData": "downloadTarget",
10+
"strategy": "class",
11+
"groups": []
12+
}
13+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"context": "chrome",
3+
"do-not-cache": true,
4+
"downloads-panel": {
5+
"selectorData": "downloadsPanel",
6+
"strategy": "id",
7+
"groups": []
8+
},
9+
10+
"menu-root": {
11+
"selectorData": "downloadsContextMenu",
12+
"strategy": "id",
13+
"groups": []
14+
},
15+
16+
"open-in-system-viewer": {
17+
"selectorData": "downloadUseSystemDefaultMenuItem",
18+
"strategy": "class",
19+
"groups": [
20+
]
21+
},
22+
23+
"always-open-in-system-viewer": {
24+
"selectorData": "downloadAlwaysUseSystemDefaultMenuItem",
25+
"strategy": "class",
26+
"groups": [
27+
]
28+
},
29+
30+
"show-in-file-browser": {
31+
"selectorData": "downloadShowMenuItem",
32+
"strategy": "class",
33+
"groups": [
34+
]
35+
},
36+
37+
"go-to-download-page": {
38+
"selectorData": "downloadOpenReferrerMenuItem",
39+
"strategy": "class",
40+
"groups": [
41+
"downloadOption"
42+
]
43+
},
44+
45+
"copy-download-link": {
46+
"selectorData": "downloadCopyLocationMenuItem",
47+
"strategy": "class",
48+
"groups": [
49+
"downloadOption"
50+
]
51+
},
52+
53+
"delete": {
54+
"selectorData": "downloadDeleteFileMenuItem",
55+
"strategy": "class",
56+
"groups": [
57+
"downloadOption"
58+
]
59+
},
60+
61+
"remove-from-history": {
62+
"selectorData": "downloadRemoveFromHistoryMenuItem",
63+
"strategy": "class",
64+
"groups": [
65+
"downloadOption"
66+
]
67+
},
68+
69+
"clear-downloads": {
70+
"selectorData": "menuitem[data-l10n-id='downloads-cmd-clear-downloads']",
71+
"strategy": "css",
72+
"groups": [
73+
"downloadOption"
74+
]
75+
}
76+
}

modules/data/generic_page.components.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,11 @@
5151
"selectorData": "dnt-on",
5252
"strategy": "id",
5353
"groups": []
54+
},
55+
56+
"pdf-link": {
57+
"selectorData": "a[href$='.pdf']",
58+
"strategy": "css",
59+
"groups": []
5460
}
5561
}

modules/data/hyperlink_context_menu.components.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
"groups": []
1414
},
1515

16+
"context-menu-save-link": {
17+
"selectorData": "context-savelink",
18+
"strategy": "id",
19+
"groups": []
20+
},
21+
1622
"context-menu-open-in-private-window": {
1723
"selectorData": "context-openlinkprivate",
1824
"strategy": "id",

modules/data/toolbar.components.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"context": "chrome",
3+
"do-not-cache": true,
4+
5+
"downloads-button": {
6+
"selectorData": "downloads-button",
7+
"strategy": "id",
8+
"groups": []
9+
},
10+
11+
"downloads-item-by-file": {
12+
"selectorData": ".downloadMainArea image[src*='{filename}']",
13+
"strategy": "css",
14+
"groups": []
15+
},
16+
17+
"blank-space-to-left": {
18+
"selectorData": "customizableui-special-spring1",
19+
"strategy": "id",
20+
"groups": []
21+
}
22+
}

modules/page_base.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
from typing import List, Union
99

1010
from pypom import Page
11-
from selenium.common.exceptions import NoSuchElementException, TimeoutException
11+
from selenium.common.exceptions import (
12+
NoAlertPresentException,
13+
NoSuchElementException,
14+
TimeoutException,
15+
)
1216
from selenium.webdriver import ActionChains, Firefox
1317
from selenium.webdriver.common.by import By
1418
from selenium.webdriver.common.keys import Keys
@@ -330,12 +334,14 @@ def get_elements(self, name: str, labels=[]):
330334
"""
331335
return self.get_element(name, multiple=True, labels=labels)
332336

333-
def get_parent_of(self, name: str, labels=[]) -> WebElement:
337+
def get_parent_of(
338+
self, reference: Union[str, tuple, WebElement], labels=[]
339+
) -> WebElement:
334340
"""
335-
Given a name (and labels if needed), return the direct parent node of the element.
341+
Given a name + labels, a WebElement, or a tuple, return the direct parent node of the element.
336342
"""
337343

338-
child = self.get_element(name, labels=labels)
344+
child = self.fetch(reference, labels=labels)
339345
return child.find_element(By.XPATH, "..")
340346

341347
def element_exists(self, name: str, labels=[]) -> Page:
@@ -386,6 +392,13 @@ def element_has_text(self, name: str, text: str, labels=[]) -> Page:
386392
)
387393
return self
388394

395+
def element_not_visible(self, name: str, labels=[]) -> Page:
396+
"""Expect helper: wait until element is not visible or timeout"""
397+
self.expect_not(
398+
EC.visibility_of_element_located(self.get_selector(name, labels=labels))
399+
)
400+
return self
401+
389402
def url_contains(self, url_part: str) -> Page:
390403
"""Expect helper: wait until driver URL contains given text or timeout"""
391404
self.expect(EC.url_contains(url_part))
@@ -616,8 +629,7 @@ def hide_popup_by_child_node(
616629
if (element && element.hidePopup) {
617630
element.hidePopup();
618631
}"""
619-
with self.driver.context(self.context_id):
620-
self.driver.execute_script(script, node)
632+
self.driver.execute_script(script, node)
621633

622634
@property
623635
def loaded(self):

0 commit comments

Comments
 (0)