-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Expand file tree
/
Copy pathelement.py
More file actions
84 lines (69 loc) · 3.1 KB
/
element.py
File metadata and controls
84 lines (69 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from bandcamp.web.base import Track, WebComponent
from bandcamp.web.locators import DiscoverPageLocator, TrackLocator
class TrackElement(WebComponent, TrackLocator):
"""Model a playable track in Bandcamp's Discover section."""
def play(self) -> None:
"""Play the track."""
if not self.is_playing:
self._get_play_button().click()
def pause(self) -> None:
"""Pause the track."""
if self.is_playing:
self._get_play_button().click()
@property
def is_playing(self) -> bool:
return "Pause" in self._get_play_button().get_attribute("aria-label")
def _get_track_info(self) -> Track:
"""Create a representation of the track's relevant information."""
full_url = self._parent.find_element(*self.URL).get_attribute("href")
# Cut off the referrer query parameter
clean_url = full_url.split("?")[0] if full_url else ""
# Some tracks don't have a genre
try:
genre = self._parent.find_element(*self.GENRE).text
except NoSuchElementException:
genre = ""
return Track(
album=self._parent.find_element(*self.ALBUM).text,
artist=self._parent.find_element(*self.ARTIST).text,
genre=genre,
url=clean_url,
)
def _get_play_button(self):
return self._parent.find_element(*self.PLAY_BUTTON)
class DiscoverTrackList(WebComponent, DiscoverPageLocator, TrackLocator):
"""Model the track list in Bandcamp's Discover section."""
def __init__(self, parent: WebElement, driver: WebDriver = None) -> None:
super().__init__(parent, driver)
self.available_tracks = self._get_available_tracks()
def load_more(self) -> None:
"""Load additional tracks in the Discover section."""
view_more_button = self._driver.find_element(*self.PAGINATION_BUTTON)
view_more_button.click()
# The button is disabled until all new tracks are loaded.
self._wait.until(EC.element_to_be_clickable(self.PAGINATION_BUTTON))
self.available_tracks = self._get_available_tracks()
def _get_available_tracks(self) -> list:
"""Find all currently available tracks in the Discover section."""
self._wait.until(
lambda driver: any(
e.is_displayed() and e.text.strip()
for e in driver.find_elements(*self.ITEM)
),
message="Timeout waiting for track text to load",
)
all_items = self._driver.find_elements(*self.ITEM)
all_tracks = []
for item in all_items:
if item.find_element(*self.PLAY_BUTTON):
all_tracks.append(item)
# Filter tracks that are displayed and have text.
return [
track
for track in all_tracks
if track.is_displayed() and track.text.strip()
]