44from selenium .webdriver .support import expected_conditions as EC
55
66from bandcamp .web .base import Track , WebComponent
7- from bandcamp .web .locators import DiscoverPageLocator , TrackLocator
7+ from bandcamp .web .locators import TrackListLocator , TrackLocator
8+
9+
10+ class TrackListElement (WebComponent ):
11+ """Model the track list on Bandcamp's Discover page."""
12+
13+ def __init__ (self , parent : WebElement , driver : WebDriver = None ) -> None :
14+ super ().__init__ (parent , driver )
15+ self .available_tracks = self ._get_available_tracks ()
16+
17+ def load_more (self ) -> None :
18+ """Load additional tracks."""
19+ view_more_button = self ._driver .find_element (
20+ * TrackListLocator .PAGINATION_BUTTON
21+ )
22+ view_more_button .click ()
23+ # The button is disabled until all new tracks are loaded.
24+ self ._wait .until (EC .element_to_be_clickable (TrackListLocator .PAGINATION_BUTTON ))
25+ self .available_tracks = self ._get_available_tracks ()
26+
27+ def _get_available_tracks (self ) -> list :
28+ """Find all currently available tracks."""
29+ self ._wait .until (
30+ self ._track_text_loaded ,
31+ message = "Timeout waiting for track text to load" ,
32+ )
33+
34+ all_tracks = self ._driver .find_elements (* TrackListLocator .ITEM )
35+
36+ # Filter tracks that are displayed and have text.
37+ return [
38+ TrackElement (track , self ._driver )
39+ for track in all_tracks
40+ if track .is_displayed () and track .text .strip ()
41+ ]
42+
43+ def _track_text_loaded (self , driver ):
44+ """Check if the track text has loaded."""
45+ return any (
46+ e .is_displayed () and e .text .strip ()
47+ for e in driver .find_elements (* TrackListLocator .ITEM )
48+ )
849
950
1051class TrackElement (WebComponent ):
11- """Model a playable track in Bandcamp's Discover section ."""
52+ """Model a playable track on Bandcamp's Discover page ."""
1253
1354 def play (self ) -> None :
1455 """Play the track."""
@@ -24,11 +65,12 @@ def pause(self) -> None:
2465 def is_playing (self ) -> bool :
2566 return "Pause" in self ._get_play_button ().get_attribute ("aria-label" )
2667
68+ def _get_play_button (self ):
69+ return self ._parent .find_element (* TrackLocator .PLAY_BUTTON )
70+
2771 def _get_track_info (self ) -> Track :
2872 """Create a representation of the track's relevant information."""
29- full_url = self ._parent .find_element (* TrackLocator .URL ).get_attribute (
30- "href"
31- )
73+ full_url = self ._parent .find_element (* TrackLocator .URL ).get_attribute ("href" )
3274 # Cut off the referrer query parameter
3375 clean_url = full_url .split ("?" )[0 ] if full_url else ""
3476 # Some tracks don't have a genre
@@ -42,53 +84,3 @@ def _get_track_info(self) -> Track:
4284 genre = genre ,
4385 url = clean_url ,
4486 )
45-
46- def _get_play_button (self ):
47- return self ._parent .find_element (* TrackLocator .PLAY_BUTTON )
48-
49-
50- class DiscoverTrackList (WebComponent ):
51- """Model the track list in Bandcamp's Discover section."""
52-
53- def __init__ (self , parent : WebElement , driver : WebDriver = None ) -> None :
54- super ().__init__ (parent , driver )
55- self .available_tracks = self ._get_available_tracks ()
56-
57- def load_more (self ) -> None :
58- """Load additional tracks in the Discover section."""
59- view_more_button = self ._driver .find_element (
60- * DiscoverPageLocator .PAGINATION_BUTTON
61- )
62- view_more_button .click ()
63- # The button is disabled until all new tracks are loaded.
64- self ._wait .until (
65- EC .element_to_be_clickable (DiscoverPageLocator .PAGINATION_BUTTON )
66- )
67- self .available_tracks = self ._get_available_tracks ()
68-
69- def _get_available_tracks (self ) -> list :
70- """Find all currently available tracks in the Discover section."""
71- self ._wait .until (
72- self ._track_text_loaded ,
73- message = "Timeout waiting for track text to load" ,
74- )
75-
76- all_items = self ._driver .find_elements (* DiscoverPageLocator .ITEM )
77- all_tracks = []
78- for item in all_items :
79- if item .find_element (* TrackLocator .PLAY_BUTTON ):
80- all_tracks .append (item )
81-
82- # Filter tracks that are displayed and have text.
83- return [
84- track
85- for track in all_tracks
86- if track .is_displayed () and track .text .strip ()
87- ]
88-
89- def _track_text_loaded (self , driver ):
90- """Check if the track text has loaded."""
91- return any (
92- e .is_displayed () and e .text .strip ()
93- for e in driver .find_elements (* DiscoverPageLocator .ITEM )
94- )
0 commit comments