Skip to content

Commit 43b67b0

Browse files
OsaSoftclaude
andcommitted
Add channel page integration tests for #247 fix
Adds a channel-videos.html fixture mirroring the real YouTube channel page DOM structure and 23 integration tests covering: video detection, URL/ID extraction, SubscriptionVideo construction, addButton() placement (verifying it doesn't crash and inserts into #meta, not above thumbnail), YouTube watched detection, and hide logic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 702cd94 commit 43b67b0

File tree

2 files changed

+470
-0
lines changed

2 files changed

+470
-0
lines changed

tests/fixtures/channel-videos.html

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<!-- Channel "Videos" tab layout (ytd-rich-grid-media inside ytd-rich-item-renderer) -->
2+
<!-- This is the layout used on channel pages like /@channel/videos -->
3+
4+
<!-- Video 1: Regular video (unwatched) -->
5+
<ytd-rich-item-renderer class="style-scope ytd-rich-grid-renderer" items-per-row="4" lockup="true" rendered-from-rich-grid="">
6+
<div id="content" class="style-scope ytd-rich-item-renderer">
7+
<ytd-rich-grid-media class="style-scope ytd-rich-item-renderer" lockup="true" mini-mode="">
8+
<div id="dismissible" class="style-scope ytd-rich-grid-media">
9+
<div id="thumbnail" class="style-scope ytd-rich-grid-media">
10+
<ytd-thumbnail class="style-scope ytd-rich-grid-media" size="large">
11+
<a id="thumbnail" class="yt-simple-endpoint inline-block style-scope ytd-thumbnail" href="/watch?v=channelVid_001">
12+
<yt-image class="style-scope ytd-thumbnail">
13+
<img src="https://i.ytimg.com/vi/channelVid_001/hqdefault.jpg">
14+
</yt-image>
15+
<div id="overlays" class="style-scope ytd-thumbnail">
16+
<ytd-thumbnail-overlay-time-status-renderer class="style-scope ytd-thumbnail">
17+
<div class="thumbnail-overlay-badge-shape style-scope ytd-thumbnail-overlay-time-status-renderer">
18+
<badge-shape class="yt-badge-shape yt-badge-shape--thumbnail-default yt-badge-shape--thumbnail-badge">
19+
<div class="yt-badge-shape__text">15:42</div>
20+
</badge-shape>
21+
</div>
22+
</ytd-thumbnail-overlay-time-status-renderer>
23+
</div>
24+
</a>
25+
</ytd-thumbnail>
26+
</div>
27+
<div id="details" class="style-scope ytd-rich-grid-media">
28+
<div id="meta" class="style-scope ytd-rich-grid-media">
29+
<h3 class="style-scope ytd-rich-grid-media">
30+
<a id="video-title-link" class="yt-simple-endpoint style-scope ytd-rich-grid-media" href="/watch?v=channelVid_001" title="Channel Video One">
31+
<yt-formatted-string id="video-title" class="style-scope ytd-rich-grid-media" title="Channel Video One">Channel Video One</yt-formatted-string>
32+
</a>
33+
</h3>
34+
<ytd-video-meta-block class="style-scope ytd-rich-grid-media">
35+
<div id="metadata-line" class="style-scope ytd-video-meta-block">
36+
<span class="inline-metadata-item style-scope ytd-video-meta-block">65k views</span>
37+
<span class="inline-metadata-item style-scope ytd-video-meta-block">3 days ago</span>
38+
</div>
39+
</ytd-video-meta-block>
40+
<div id="buttons" class="style-scope ytd-rich-grid-media"></div>
41+
</div>
42+
<div id="menu" class="style-scope ytd-rich-grid-media">
43+
<ytd-menu-renderer class="style-scope ytd-rich-grid-media"></ytd-menu-renderer>
44+
</div>
45+
</div>
46+
</div>
47+
</ytd-rich-grid-media>
48+
</div>
49+
</ytd-rich-item-renderer>
50+
51+
<!-- Video 2: Regular video (with progress bar - partially watched) -->
52+
<ytd-rich-item-renderer class="style-scope ytd-rich-grid-renderer" items-per-row="4" lockup="true" rendered-from-rich-grid="">
53+
<div id="content" class="style-scope ytd-rich-item-renderer">
54+
<ytd-rich-grid-media class="style-scope ytd-rich-item-renderer" lockup="true" mini-mode="">
55+
<div id="dismissible" class="style-scope ytd-rich-grid-media">
56+
<div id="thumbnail" class="style-scope ytd-rich-grid-media">
57+
<ytd-thumbnail class="style-scope ytd-rich-grid-media" size="large">
58+
<a id="thumbnail" class="yt-simple-endpoint inline-block style-scope ytd-thumbnail" href="/watch?v=channelVid_002">
59+
<yt-image class="style-scope ytd-thumbnail">
60+
<img src="https://i.ytimg.com/vi/channelVid_002/hqdefault.jpg">
61+
</yt-image>
62+
<div id="overlays" class="style-scope ytd-thumbnail">
63+
<ytd-thumbnail-overlay-time-status-renderer class="style-scope ytd-thumbnail">
64+
<div class="thumbnail-overlay-badge-shape style-scope ytd-thumbnail-overlay-time-status-renderer">
65+
<badge-shape class="yt-badge-shape yt-badge-shape--thumbnail-default yt-badge-shape--thumbnail-badge">
66+
<div class="yt-badge-shape__text">22:10</div>
67+
</badge-shape>
68+
</div>
69+
</ytd-thumbnail-overlay-time-status-renderer>
70+
</div>
71+
<div class="ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment" style="width: 45%;"></div>
72+
</a>
73+
</ytd-thumbnail>
74+
</div>
75+
<div id="details" class="style-scope ytd-rich-grid-media">
76+
<div id="meta" class="style-scope ytd-rich-grid-media">
77+
<h3 class="style-scope ytd-rich-grid-media">
78+
<a id="video-title-link" class="yt-simple-endpoint style-scope ytd-rich-grid-media" href="/watch?v=channelVid_002" title="Channel Video Two">
79+
<yt-formatted-string id="video-title" class="style-scope ytd-rich-grid-media" title="Channel Video Two">Channel Video Two</yt-formatted-string>
80+
</a>
81+
</h3>
82+
<ytd-video-meta-block class="style-scope ytd-rich-grid-media">
83+
<div id="metadata-line" class="style-scope ytd-video-meta-block">
84+
<span class="inline-metadata-item style-scope ytd-video-meta-block">120k views</span>
85+
<span class="inline-metadata-item style-scope ytd-video-meta-block">1 week ago</span>
86+
</div>
87+
</ytd-video-meta-block>
88+
<div id="buttons" class="style-scope ytd-rich-grid-media"></div>
89+
</div>
90+
</div>
91+
</div>
92+
</ytd-rich-grid-media>
93+
</div>
94+
</ytd-rich-item-renderer>
95+
96+
<!-- Video 3: Short -->
97+
<ytd-rich-item-renderer class="style-scope ytd-rich-grid-renderer" items-per-row="4" lockup="true" rendered-from-rich-grid="">
98+
<div id="content" class="style-scope ytd-rich-item-renderer">
99+
<ytd-rich-grid-media class="style-scope ytd-rich-item-renderer" lockup="true" mini-mode="">
100+
<div id="dismissible" class="style-scope ytd-rich-grid-media">
101+
<div id="thumbnail" class="style-scope ytd-rich-grid-media">
102+
<ytd-thumbnail class="style-scope ytd-rich-grid-media" size="large">
103+
<a id="thumbnail" class="yt-simple-endpoint inline-block style-scope ytd-thumbnail" href="/shorts/channelShort_001">
104+
<yt-image class="style-scope ytd-thumbnail">
105+
<img src="https://i.ytimg.com/vi/channelShort_001/hqdefault.jpg">
106+
</yt-image>
107+
</a>
108+
</ytd-thumbnail>
109+
</div>
110+
<div id="details" class="style-scope ytd-rich-grid-media">
111+
<div id="meta" class="style-scope ytd-rich-grid-media">
112+
<h3 class="style-scope ytd-rich-grid-media">
113+
<a id="video-title-link" class="yt-simple-endpoint style-scope ytd-rich-grid-media" href="/shorts/channelShort_001" title="Channel Short">
114+
<yt-formatted-string id="video-title" class="style-scope ytd-rich-grid-media" title="Channel Short">Channel Short</yt-formatted-string>
115+
</a>
116+
</h3>
117+
</div>
118+
</div>
119+
</div>
120+
</ytd-rich-grid-media>
121+
</div>
122+
</ytd-rich-item-renderer>
123+
124+
<!-- Video 4: Livestream -->
125+
<ytd-rich-item-renderer class="style-scope ytd-rich-grid-renderer" items-per-row="4" lockup="true" rendered-from-rich-grid="">
126+
<div id="content" class="style-scope ytd-rich-item-renderer">
127+
<ytd-rich-grid-media class="style-scope ytd-rich-item-renderer" lockup="true" mini-mode="">
128+
<div id="dismissible" class="style-scope ytd-rich-grid-media">
129+
<div id="thumbnail" class="style-scope ytd-rich-grid-media">
130+
<ytd-thumbnail class="style-scope ytd-rich-grid-media" size="large">
131+
<a id="thumbnail" class="yt-simple-endpoint inline-block style-scope ytd-thumbnail" href="/watch?v=channelLive_001">
132+
<yt-image class="style-scope ytd-thumbnail">
133+
<img src="https://i.ytimg.com/vi/channelLive_001/hqdefault.jpg">
134+
</yt-image>
135+
<div id="overlays" class="style-scope ytd-thumbnail">
136+
<ytd-thumbnail-overlay-time-status-renderer class="style-scope ytd-thumbnail">
137+
<div class="thumbnail-overlay-badge-shape style-scope ytd-thumbnail-overlay-time-status-renderer">
138+
<badge-shape class="yt-badge-shape yt-badge-shape--thumbnail-live yt-badge-shape--thumbnail-badge">
139+
<div class="yt-badge-shape__text">LIVE</div>
140+
</badge-shape>
141+
</div>
142+
</ytd-thumbnail-overlay-time-status-renderer>
143+
</div>
144+
</a>
145+
</ytd-thumbnail>
146+
</div>
147+
<div id="details" class="style-scope ytd-rich-grid-media">
148+
<div id="meta" class="style-scope ytd-rich-grid-media">
149+
<h3 class="style-scope ytd-rich-grid-media">
150+
<a id="video-title-link" class="yt-simple-endpoint style-scope ytd-rich-grid-media" href="/watch?v=channelLive_001" title="Channel Livestream">
151+
<yt-formatted-string id="video-title" class="style-scope ytd-rich-grid-media" title="Channel Livestream">Channel Livestream</yt-formatted-string>
152+
</a>
153+
</h3>
154+
</div>
155+
</div>
156+
</div>
157+
</ytd-rich-grid-media>
158+
</div>
159+
</ytd-rich-item-renderer>

0 commit comments

Comments
 (0)