social-agent-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/knowledge/x.md ADDED
@@ -0,0 +1,1532 @@
1
+ # X (Twitter) Platform Bilgi Dosyasi
2
+
3
+ Bu dosya, X (Twitter) platformunda browser otomasyonu icin gereken tum bilgileri icerir.
4
+ AI mapper ve planner bu dosyayi okuyarak selector'leri, URL pattern'lerini ve kullanici
5
+ etkilesim akislarini ogrenir.
6
+
7
+ > Son guncelleme: 2026-03-14
8
+
9
+ ---
10
+
11
+ ## 1. URL Yapisi
12
+
13
+ ### Ana Sayfalar
14
+
15
+ | Sayfa | URL | Aciklama |
16
+ |-------|-----|----------|
17
+ | Ana Sayfa | `https://x.com/home` | Timeline (For You / Following sekmeleri) |
18
+ | Kesfet | `https://x.com/explore` | Explore sayfasi, trending konular |
19
+ | Bildirimler | `https://x.com/notifications` | Tum bildirimler |
20
+ | Bildirimler (Bahsetmeler) | `https://x.com/notifications/mentions` | Sadece mention'lar |
21
+ | Mesajlar | `https://x.com/messages` | DM listesi |
22
+ | Mesaj Detay | `https://x.com/messages/CONVERSATION_ID` | Belirli bir DM konusmasi |
23
+ | Yer Imleri | `https://x.com/i/bookmarks` | Kaydedilen tweet'ler |
24
+ | Listeler | `https://x.com/USERNAME/lists` | Kullanicinin listeleri |
25
+ | Belirli Liste | `https://x.com/i/lists/LIST_ID` | Tek bir liste |
26
+ | Ayarlar | `https://x.com/settings` | Ana ayarlar |
27
+ | Hesap Ayarlari | `https://x.com/settings/account` | Hesap ayarlari |
28
+ | Gizlilik Ayarlari | `https://x.com/settings/privacy_and_safety` | Gizlilik |
29
+ | Goruntuleme Ayarlari | `https://x.com/settings/display` | Tema, yazi boyutu |
30
+ | Compose (Modal) | `https://x.com/compose/post` | Direkt tweet yazma sayfasi (modal acar) |
31
+ | Gece Modu | `https://x.com/settings/display` | Karanlik/aydinlik tema |
32
+
33
+ ### Profil URL'leri
34
+
35
+ | Sayfa | URL | Aciklama |
36
+ |-------|-----|----------|
37
+ | Profil | `https://x.com/USERNAME` | Kullanici profil sayfasi |
38
+ | Profil (Tweetler) | `https://x.com/USERNAME` | Varsayilan sekme |
39
+ | Profil (Yanitlar) | `https://x.com/USERNAME/with_replies` | Tweetler + yanitlar |
40
+ | Profil (Medya) | `https://x.com/USERNAME/media` | Sadece gorseller/videolar |
41
+ | Profil (Begeniler) | `https://x.com/USERNAME/likes` | Begenilen tweetler |
42
+ | Takipciler | `https://x.com/USERNAME/followers` | Takipci listesi |
43
+ | Takip Edilenler | `https://x.com/USERNAME/following` | Takip edilen listesi |
44
+ | Verified Takipciler | `https://x.com/USERNAME/verified_followers` | Dogrulanmis takipciler |
45
+
46
+ ### Tweet URL'leri
47
+
48
+ | Sayfa | URL | Aciklama |
49
+ |-------|-----|----------|
50
+ | Tekil Tweet | `https://x.com/USERNAME/status/TWEET_ID` | Tweet detay sayfasi |
51
+ | Tweet Fotosu | `https://x.com/USERNAME/status/TWEET_ID/photo/1` | Tweet'in gorseli (1-4) |
52
+ | Tweet Begenenler | `https://x.com/USERNAME/status/TWEET_ID/likes` | Begenen kullanicilar |
53
+ | Tweet Retweet'ler | `https://x.com/USERNAME/status/TWEET_ID/retweets` | Retweet yapanlar |
54
+ | Tweet Alintilar | `https://x.com/USERNAME/status/TWEET_ID/quotes` | Alintilayan tweetler |
55
+ | Quote Tweet | `https://x.com/compose/post?quote=TWEET_ID` | Alintili tweet yazma |
56
+
57
+ ### Arama URL'leri
58
+
59
+ | Arama Turu | URL | Aciklama |
60
+ |------------|-----|----------|
61
+ | Genel Arama | `https://x.com/search?q=QUERY` | Varsayilan arama (Top) |
62
+ | En Son | `https://x.com/search?q=QUERY&f=live` | Zaman sirali sonuclar |
63
+ | Kisiler | `https://x.com/search?q=QUERY&f=user` | Kullanici arama |
64
+ | Medya | `https://x.com/search?q=QUERY&f=media` | Gorsel/video sonuclar |
65
+ | Listeler | `https://x.com/search?q=QUERY&f=list` | Liste arama |
66
+
67
+ ### Gelismis Arama Operatorleri
68
+
69
+ ```
70
+ from:USERNAME → Belirli kullanicidan
71
+ to:USERNAME → Belirli kullaniciya yanit
72
+ @USERNAME → Mention iceren
73
+ #hashtag → Hashtag iceren
74
+ "tam ifade" → Tam eslesme
75
+ min_retweets:100 → En az 100 retweet
76
+ min_faves:100 → En az 100 begeni
77
+ min_replies:10 → En az 10 yanit
78
+ lang:tr → Turkce tweetler
79
+ since:2025-01-01 → Tarihten sonra
80
+ until:2025-12-31 → Tarihten once
81
+ filter:images → Gorsel iceren
82
+ filter:videos → Video iceren
83
+ filter:links → Link iceren
84
+ filter:media → Medya iceren (gorsel veya video)
85
+ -filter:replies → Yanitlari haric tut
86
+ -filter:retweets → Retweet'leri haric tut
87
+ filter:verified → Dogrulanmis hesaplardan
88
+ filter:follows → Takip ettigim kisilerden
89
+ filter:has_engagement → Etkilesim almis tweetler
90
+ near:Istanbul → Lokasyona yakin
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 2. data-testid Selectorleri (KRITIK)
96
+
97
+ X platformu React tabanlidir ve `data-testid` attribute'larini yogun sekilde kullanir.
98
+ Bu selector'ler en guvenilir olanlaridir ve nadiren degisir.
99
+
100
+ ### 2.1 Tweet / Post Selectorleri
101
+
102
+ | Selector | Aciklama | Kullanim |
103
+ |----------|----------|----------|
104
+ | `[data-testid="tweet"]` | Tek bir tweet karti | Timeline'daki her tweet |
105
+ | `[data-testid="tweetText"]` | Tweet metin icerigi | Tweet icerigini okumak icin |
106
+ | `[data-testid="cellInnerDiv"]` | Timeline hucre wrapper | Timeline'daki her eleman |
107
+ | `[data-testid="tweetPhoto"]` | Tweet'teki gorsel | Gorsele tiklamak icin |
108
+ | `[data-testid="videoPlayer"]` | Tweet'teki video | Video oynatici |
109
+ | `[data-testid="videoComponent"]` | Video bilesei | Video container |
110
+ | `[data-testid="card.wrapper"]` | Link onizleme karti | URL card |
111
+ | `[data-testid="card.layoutLarge.media"]` | Buyuk kart gorseli | Link preview gorseli |
112
+ | `[data-testid="card.layoutSmall.media"]` | Kucuk kart gorseli | Kucuk link preview |
113
+
114
+ ### 2.2 Tweet Aksiyon Butonlari
115
+
116
+ | Selector | Aciklama | Durum |
117
+ |----------|----------|-------|
118
+ | `[data-testid="reply"]` | Yanit butonu | Her tweet'te |
119
+ | `[data-testid="retweet"]` | Retweet butonu | Henuz retweet yapilmamis |
120
+ | `[data-testid="unretweet"]` | Retweet geri al | Retweet yapilmis durumda |
121
+ | `[data-testid="like"]` | Begeni butonu | Henuz begenilmemis |
122
+ | `[data-testid="unlike"]` | Begeni geri al | Begenilmis durumda |
123
+ | `[data-testid="bookmark"]` | Yer imi ekle butonu | Kaydedilmemis |
124
+ | `[data-testid="removeBookmark"]` | Yer imi kaldir | Kaydedilmis durumda |
125
+ | `[data-testid="share"]` | Paylasim butonu (ok ikonu) | Her tweet'te (iOS share icon) |
126
+ | `[data-testid="caret"]` | Uc nokta menusu (...) | Tweet'in sag ust kosesinde |
127
+
128
+ **Onemli Not:** Retweet butonuna tiklandiginda bir dropdown menu acilir:
129
+ - "Repost" secenegi: Direkt retweet
130
+ - "Quote" secenegi: Alintili tweet
131
+
132
+ ### 2.3 Compose (Tweet Yazma) Selectorleri
133
+
134
+ | Selector | Aciklama | Yer |
135
+ |----------|----------|-----|
136
+ | `[data-testid="SideNav_NewTweet_Button"]` | Sol menudeki "Post" butonu | Sol sidebar (her zaman gorunur) |
137
+ | `[data-testid="tweetTextarea_0"]` | Tweet metin alani (ilk) | Compose modal/alan |
138
+ | `[data-testid="tweetTextarea_1"]` | Tweet metin alani (thread 2. tweet) | Thread yazarken |
139
+ | `[data-testid="tweetTextarea_2"]` | Tweet metin alani (thread 3. tweet) | Thread yazarken |
140
+ | `[data-testid="tweetButton"]` | "Post" gonderi butonu (modal) | Compose modal |
141
+ | `[data-testid="tweetButtonInline"]` | "Post" gonderi butonu (inline) | Ana sayfadaki compose alani |
142
+ | `[data-testid="toolBar"]` | Compose araclari cubugu | Alt araclari (gorsel, emoji vs.) |
143
+ | `[data-testid="fileInput"]` | Dosya yuklemek icin gizli input | `<input type="file">` - display:none |
144
+ | `[data-testid="addButton"]` | Thread'e yeni tweet ekle (+) | Thread yazarken |
145
+ | `[data-testid="attachments"]` | Eklenmis medya onizleme alani | Gorsel/video eklendikten sonra |
146
+ | `[data-testid="removeMedia"]` | Eklenen gorseli kaldir (X) | Gorsel onizlemesinin ustunde |
147
+ | `[data-testid="gifSearchButton"]` | GIF arama butonu | Compose toolbar'da |
148
+ | `[data-testid="emojiButton"]` | Emoji secici butonu | Compose toolbar'da |
149
+ | `[data-testid="geoButton"]` | Konum ekleme butonu | Compose toolbar'da |
150
+ | `[data-testid="scheduledButton"]` | Zamanlanmis tweet butonu | Compose toolbar'da (takvim ikonu) |
151
+ | `[data-testid="Dropdown"]` | Tweet'in kime gorunur olacagi | "Everyone can reply" secici |
152
+
153
+ ### 2.4 Navigasyon Selectorleri (Sol Sidebar)
154
+
155
+ | Selector | Aciklama |
156
+ |----------|----------|
157
+ | `[data-testid="AppTabBar_Home_Link"]` | Ana Sayfa linki |
158
+ | `[data-testid="AppTabBar_Explore_Link"]` | Kesfet linki |
159
+ | `[data-testid="AppTabBar_Notifications_Link"]` | Bildirimler linki |
160
+ | `[data-testid="AppTabBar_DirectMessage_Link"]` | Mesajlar linki |
161
+ | `[data-testid="AppTabBar_Profile_Link"]` | Profil linki |
162
+ | `[data-testid="SideNav_NewTweet_Button"]` | Yeni Tweet butonu |
163
+ | `[data-testid="AppTabBar_More_Menu"]` | Daha fazla menusu |
164
+
165
+ ### 2.5 Profil Selectorleri
166
+
167
+ | Selector | Aciklama |
168
+ |----------|----------|
169
+ | `[data-testid="UserAvatar-Container-USERNAME"]` | Kullanici avatar container'i |
170
+ | `[data-testid="UserName"]` | Kullanici adi (gorunen ad) |
171
+ | `[data-testid="UserDescription"]` | Profil biyografisi |
172
+ | `[data-testid="UserUrl"]` | Profildeki web sitesi linki |
173
+ | `[data-testid="UserProfileHeader_Items"]` | Profil baslik bilgileri (konum, tarih vs.) |
174
+ | `[data-testid="userActions"]` | Profildeki aksiyon butonu (uc nokta) |
175
+ | `[data-testid="editProfileButton"]` | Profili duzenle butonu (kendi profilinde) |
176
+ | `[data-testid="placementTracking"]` | Takip/Takibi birak butonu container |
177
+ | `[data-testid="UserCell"]` | Kullanici listesi hucre (follower/following listelerinde) |
178
+ | `[data-testid="UserProfileSchema"]` | Profil schema verisi |
179
+
180
+ **Follow/Unfollow butonlari icin:**
181
+ - Takip et: `[data-testid="USERNAME-follow"]` veya `[data-testid="follow"]` (profil sayfasinda `Follow` metinli buton)
182
+ - Takibi birak: `[data-testid="USERNAME-unfollow"]` veya profil sayfasinda "Following" metinli buton (hover'da "Unfollow" olur)
183
+
184
+ ### 2.6 Arama Selectorleri
185
+
186
+ | Selector | Aciklama |
187
+ |----------|----------|
188
+ | `[data-testid="SearchBox_Search_Input"]` | Arama input alani |
189
+ | `[data-testid="SearchBox_Search_Input_label"]` | Arama input label |
190
+ | `[data-testid="searchBoxClearButton"]` | Arama temizle butonu (X) |
191
+ | `[data-testid="typeaheadResult"]` | Arama oneri sonucu |
192
+
193
+ ### 2.7 DM (Mesajlar) Selectorleri
194
+
195
+ | Selector | Aciklama |
196
+ |----------|----------|
197
+ | `[data-testid="DmScrollerContainer"]` | DM mesaj listesi scroll container |
198
+ | `[data-testid="dmComposerTextInput"]` | DM mesaj yazma alani |
199
+ | `[data-testid="dmComposerSendButton"]` | DM gonderme butonu |
200
+ | `[data-testid="conversation"]` | DM konusma karti |
201
+ | `[data-testid="newDirectMessage"]` | Yeni mesaj olustur butonu (zarf + ikonu) |
202
+ | `[data-testid="DM_Conversation_Avatar"]` | DM konusma avatar |
203
+ | `[data-testid="messageEntry"]` | Tek bir DM mesaj baloncugu |
204
+
205
+ ### 2.8 Modal ve Dialog Selectorleri
206
+
207
+ | Selector | Aciklama |
208
+ |----------|----------|
209
+ | `[data-testid="mask"]` | Modal arka plan mask (tiklanarak kapatilir) |
210
+ | `[data-testid="sheetDialog"]` | Sheet dialog container |
211
+ | `[data-testid="confirmationSheetDialog"]` | Onay dialogu |
212
+ | `[data-testid="confirmationSheetConfirm"]` | Onay dialog "Onayla" butonu |
213
+ | `[data-testid="confirmationSheetCancel"]` | Onay dialog "Iptal" butonu |
214
+ | `[data-testid="app-bar-close"]` | Modal kapat butonu (X) |
215
+ | `[data-testid="app-bar-back"]` | Modal geri butonu |
216
+
217
+ ### 2.9 Timeline ve Feed Selectorleri
218
+
219
+ | Selector | Aciklama |
220
+ |----------|----------|
221
+ | `[data-testid="primaryColumn"]` | Ana icerik kolonu (orta) |
222
+ | `[data-testid="sidebarColumn"]` | Sag sidebar (trending, who to follow) |
223
+ | `[data-testid="ScrollSnap-List"]` | Yatay scroll listesi (sekme basliklari) |
224
+ | `[data-testid="TabBarItemLink"]` | Sekme bar linkleri ("For You", "Following") |
225
+
226
+ ### 2.10 Diger Onemli Selectorler
227
+
228
+ | Selector | Aciklama |
229
+ |----------|----------|
230
+ | `[data-testid="trend"]` | Trending konu karti |
231
+ | `[data-testid="UserCell"]` | Who to follow kullanici karti |
232
+ | `[data-testid="socialContext"]` | "X liked" / "X retweeted" sosyal context |
233
+ | `[data-testid="emptyState"]` | Bos durum mesaji |
234
+ | `[data-testid="toast"]` | Toast bildirim mesaji |
235
+ | `[data-testid="inline-reply-offscreen"]` | Inline yanit alani (goruntulenmez) |
236
+ | `[data-testid="swipe-to-dismiss"]` | Swipe ile kapatma alani |
237
+ | `[data-testid="settingsLink"]` | Ayarlar linki |
238
+ | `[data-testid="communityShareButton"]` | Community paylas butonu |
239
+ | `[data-testid="Dropdown"]` | Genel dropdown menuleri |
240
+ | `[data-testid="Typeahead"]` | Autocomplete sonuclari |
241
+
242
+ ---
243
+
244
+ ## 3. aria-label Selectorleri (Yedek)
245
+
246
+ data-testid bulunamazsa aria-label kullanilabilir. Dile bagli olarak degisir.
247
+
248
+ ### Ingilizce Arayuz
249
+
250
+ ```
251
+ [aria-label="Home"] → Ana sayfa
252
+ [aria-label="Search"] → Arama
253
+ [aria-label="Notifications"] → Bildirimler
254
+ [aria-label="Messages"] → Mesajlar
255
+ [aria-label="Post"] → Tweet/Post butonu
256
+ [aria-label="Like"] → Begeni
257
+ [aria-label="Unlike"] → Begeni geri al
258
+ [aria-label="Repost"] → Retweet
259
+ [aria-label="Undo repost"] → Retweet geri al
260
+ [aria-label="Reply"] → Yanit
261
+ [aria-label="Share post"] → Paylasim
262
+ [aria-label="More"] → Uc nokta menusu
263
+ [aria-label="Follow @USERNAME"] → Takip et
264
+ [aria-label="Following @USERNAME"] → Takip ediliyor (hover: Unfollow)
265
+ [aria-label="Search query"] → Arama input alani
266
+ [aria-label="Timeline: "] → Timeline container
267
+ [aria-label="Profile"] → Profil
268
+ [aria-label="Close"] → Kapat butonu
269
+ [aria-label="Back"] → Geri butonu
270
+ [aria-label="Add photos or video"] → Medya ekle butonu
271
+ [aria-label="Add emoji"] → Emoji ekle
272
+ [aria-label="Add GIF"] → GIF ekle
273
+ [aria-label="Schedule"] → Zamanla
274
+ ```
275
+
276
+ ### Turkce Arayuz
277
+
278
+ ```
279
+ [aria-label="Ana sayfa"] → Ana sayfa
280
+ [aria-label="Ara"] → Arama
281
+ [aria-label="Bildirimler"] → Bildirimler
282
+ [aria-label="Mesajlar"] → Mesajlar
283
+ [aria-label="Gonderi"] → Tweet/Post butonu
284
+ [aria-label="Begen"] → Begeni
285
+ [aria-label="Begenme"] → Begeni geri al
286
+ [aria-label="Yeniden gonderi"] → Retweet
287
+ [aria-label="Yanitla"] → Yanit
288
+ [aria-label="Paylas"] → Paylasim
289
+ [aria-label="Daha fazla"] → Uc nokta menusu
290
+ [aria-label="@USERNAME kullanicisini takip et"] → Takip et
291
+ [aria-label="Kapat"] → Kapat
292
+ [aria-label="Geri"] → Geri
293
+ ```
294
+
295
+ ---
296
+
297
+ ## 4. role Tabanlı Selectorler
298
+
299
+ ```css
300
+ [role="dialog"] → Acik modal/dialog
301
+ [role="menu"] → Dropdown menu (retweet, caret menusu vs.)
302
+ [role="menuitem"] → Menu secenegi
303
+ [role="article"] → Tek tweet container (tweet icinde)
304
+ [role="button"] → Tiklanabilir buton
305
+ [role="link"] → Link
306
+ [role="tab"] → Sekme (For You / Following)
307
+ [role="tablist"] → Sekme grubu
308
+ [role="progressbar"] → Yukleniyor gostergesi
309
+ [role="alertdialog"] → Uyari dialogu
310
+ [role="textbox"] → Metin giris alani (compose)
311
+ [role="complementary"] → Sidebar icerigi
312
+ [role="navigation"] → Navigasyon alani
313
+ [role="banner"] → Header alani
314
+ [role="main"] → Ana icerik
315
+ [role="region"] → Icerik bolumü
316
+ [role="group"] → Tweet aksiyonlari grubu
317
+ ```
318
+
319
+ ---
320
+
321
+ ## 5. UI Navigasyon Yapisi
322
+
323
+ ### 5.1 Genel Sayfa Duazeni
324
+
325
+ ```
326
+ ┌──────────────────────────────────────────────────────────────┐
327
+ │ Header │
328
+ ├────────────┬─────────────────────────┬───────────────────────┤
329
+ │ │ │ │
330
+ │ Sol │ Ana Icerik │ Sag Sidebar │
331
+ │ Sidebar │ (primaryColumn) │ (sidebarColumn) │
332
+ │ │ │ │
333
+ │ - Home │ ┌─────────────────┐ │ ┌───────────────┐ │
334
+ │ - Explore │ │ For You │Follow │ │ │ Search Box │ │
335
+ │ - Notif. │ ├─────────────────┤ │ ├───────────────┤ │
336
+ │ - Messages│ │ Tweet 1 │ │ │ Trending │ │
337
+ │ - Grok │ │ Tweet 2 │ │ │ Who to Follow │ │
338
+ │ - Premium │ │ Tweet 3 │ │ │ Footer Links │ │
339
+ │ - Profile │ │ ... │ │ └───────────────┘ │
340
+ │ - More │ └─────────────────┘ │ │
341
+ │ │ │ │
342
+ │ [Post btn] │ │ │
343
+ │ │ │ │
344
+ └────────────┴─────────────────────────┴───────────────────────┘
345
+ ```
346
+
347
+ ### 5.2 Sol Sidebar Navigasyon Sirasi
348
+
349
+ 1. X logosu (Ana sayfaya gider)
350
+ 2. Home / Ana Sayfa
351
+ 3. Explore / Kesfet
352
+ 4. Notifications / Bildirimler
353
+ 5. Messages / Mesajlar
354
+ 6. Grok (AI asistan)
355
+ 7. Communities / Topluluklar
356
+ 8. Premium
357
+ 9. Verified Orgs
358
+ 10. Profile / Profil
359
+ 11. More / Daha Fazla (alt menu acar)
360
+ 12. **Post butonu** (en altta, buyuk mavi buton)
361
+
362
+ ### 5.3 More (Daha Fazla) Alt Menusu
363
+
364
+ `[data-testid="AppTabBar_More_Menu"]` tiklandiginda acilan menu:
365
+ - Bookmarks / Yer Imleri
366
+ - Spaces
367
+ - Monetization
368
+ - Ads
369
+ - Jobs
370
+ - Lists / Listeler
371
+ - Creator Studio
372
+ - Analytics
373
+ - Settings and Support → alt menu:
374
+ - Settings and privacy
375
+ - Help Center
376
+ - Display
377
+ - Keyboard shortcuts
378
+
379
+ ### 5.4 Sag Sidebar
380
+
381
+ - Arama kutusu (`[data-testid="SearchBox_Search_Input"]`)
382
+ - Premium ol / Premium ozellikleri
383
+ - Trending konular (`[data-testid="trend"]`)
384
+ - Who to Follow / Takip Onerileri (`[data-testid="UserCell"]`)
385
+ - Footer linkleri (Terms, Privacy, vb.)
386
+
387
+ ---
388
+
389
+ ## 6. Kullanici Etkilesim Adim Adimlari
390
+
391
+ ### 6.1 Tweet (Post) Atma
392
+
393
+ **Yontem A: Sol sidebar butonuyla**
394
+ ```
395
+ 1. [click] "Post" butonuna tikla
396
+ → selector: [data-testid="SideNav_NewTweet_Button"]
397
+ → fallback: a[href="/compose/post"], [aria-label="Post"], [aria-label="Gonderi"]
398
+
399
+ 2. [wait] Compose modal acilana kadar bekle
400
+ → waitMs: 1000
401
+ → Acilan modal: [role="dialog"] icerisinde compose alani
402
+
403
+ 3. [click] Metin alanina tikla (fokus al)
404
+ → selector: [data-testid="tweetTextarea_0"]
405
+ → fallback: [role="textbox"][data-testid="tweetTextarea_0"], div[contenteditable="true"][data-testid="tweetTextarea_0"]
406
+
407
+ 4. [type] Icerigi yaz
408
+ → selector: [data-testid="tweetTextarea_0"]
409
+ → value: {{CONTENT}}
410
+ → NOT: Bu bir <input> veya <textarea> DEGILDIR!
411
+ → contenteditable div'dir. Normal type calismayabilir.
412
+ → Playwright: page.fill() veya page.type() kullanilabilir
413
+ → Alternatif: tikla + keyboard.type() ile yaz
414
+
415
+ 5. [wait] Metin girdikten sonra kisa bekle
416
+ → waitMs: 500
417
+
418
+ 6. [click] "Post" butonuna tikla
419
+ → selector: [data-testid="tweetButton"]
420
+ → fallback: [data-testid="tweetButton"][role="button"]
421
+ → NOT: Buton metin girilene kadar disabled olabilir
422
+ ```
423
+
424
+ **Yontem B: Ana sayfadaki inline compose**
425
+ ```
426
+ 1. [goto] Ana sayfaya git
427
+ → url: https://x.com/home
428
+
429
+ 2. [click] Ana sayfadaki compose alanina tikla
430
+ → selector: [data-testid="tweetTextarea_0"]
431
+ → fallback: div[contenteditable="true"]
432
+
433
+ 3. [type] Icerigi yaz
434
+ → selector: [data-testid="tweetTextarea_0"]
435
+ → value: {{CONTENT}}
436
+
437
+ 4. [click] "Post" butonuna tikla
438
+ → selector: [data-testid="tweetButtonInline"]
439
+ → fallback: [data-testid="tweetButtonInline"][role="button"]
440
+ ```
441
+
442
+ **Yontem C: URL ile direkt compose**
443
+ ```
444
+ 1. [goto] Compose sayfasina git
445
+ → url: https://x.com/compose/post
446
+
447
+ 2. [wait] Modal acilmasini bekle
448
+ → waitMs: 1500
449
+
450
+ 3. [type] Icerigi yaz
451
+ → selector: [data-testid="tweetTextarea_0"]
452
+ → value: {{CONTENT}}
453
+
454
+ 4. [click] "Post" butonuna tikla
455
+ → selector: [data-testid="tweetButton"]
456
+ ```
457
+
458
+ ### 6.2 Gorsel/Medya ile Tweet Atma
459
+
460
+ ```
461
+ 1. [click] Post butonuna tikla
462
+ → selector: [data-testid="SideNav_NewTweet_Button"]
463
+
464
+ 2. [wait] Modal acilmasini bekle
465
+ → waitMs: 1000
466
+
467
+ 3. [type] Metin yaz (istege bagli)
468
+ → selector: [data-testid="tweetTextarea_0"]
469
+ → value: {{CONTENT}}
470
+
471
+ 4. [upload] Gorsel yukle
472
+ → selector: [data-testid="fileInput"]
473
+ → NOT: Bu gizli (display:none) bir <input type="file"> elementidir
474
+ → Playwright: page.setInputFiles('[data-testid="fileInput"]', '{{IMAGE_PATH}}')
475
+ → Birden fazla gorsel: dizi olarak gonder (maks 4 gorsel)
476
+ → fallback: input[type="file"][data-testid="fileInput"]
477
+
478
+ 5. [wait] Gorsel yuklenmesini bekle
479
+ → waitMs: 3000
480
+ → Gorsel yuklenince [data-testid="attachments"] gorulur
481
+
482
+ 6. [click] "Post" butonuna tikla
483
+ → selector: [data-testid="tweetButton"]
484
+ ```
485
+
486
+ ### 6.3 Tweet Begenmie
487
+
488
+ ```
489
+ 1. [goto] Tweet sayfasina git (eger URL verilmisse)
490
+ → url: {{TWEET_URL}}
491
+
492
+ 2. [wait] Sayfa yuklenmesini bekle
493
+ → waitMs: 2000
494
+
495
+ 3. [click] Begeni butonuna tikla
496
+ → selector: [data-testid="like"]
497
+ → fallback: [aria-label*="Like"], [aria-label*="Begen"]
498
+ → NOT: Eger tweet zaten begenilmisse, [data-testid="unlike"] gorulur.
499
+ → Bu durumda islem yapilmamali.
500
+ ```
501
+
502
+ **Timeline'daki belirli bir tweeti begenme:**
503
+ ```
504
+ 1. Tweet'i bul: [data-testid="tweet"] icinde metni ara
505
+ 2. O tweet icindeki [data-testid="like"] butonuna tikla
506
+ → selector: article[data-testid="tweet"]:has-text("{{SEARCH_TEXT}}") [data-testid="like"]
507
+ ```
508
+
509
+ ### 6.4 Retweet Yapma
510
+
511
+ ```
512
+ 1. [goto] Tweet sayfasina git
513
+ → url: {{TWEET_URL}}
514
+
515
+ 2. [wait] Sayfa yuklenmesini bekle
516
+ → waitMs: 2000
517
+
518
+ 3. [click] Retweet butonuna tikla
519
+ → selector: [data-testid="retweet"]
520
+ → fallback: [aria-label*="Repost"], [aria-label*="Yeniden gonderi"]
521
+ → NOT: Eger zaten retweet yapilmissa [data-testid="unretweet"] gorulur
522
+
523
+ 4. [wait] Dropdown menu acilmasini bekle
524
+ → waitMs: 500
525
+
526
+ 5. [click] "Repost" secenegine tikla
527
+ → selector: [data-testid="retweetConfirm"]
528
+ → fallback: [role="menuitem"]:first-child, [role="menu"] [role="menuitem"]:has-text("Repost")
529
+ → NOT: Menu 2 secenek icerir: "Repost" ve "Quote"
530
+ ```
531
+
532
+ ### 6.5 Alintili Tweet (Quote Tweet)
533
+
534
+ ```
535
+ 1. [goto] Tweet sayfasina git
536
+ → url: {{TWEET_URL}}
537
+
538
+ 2. [wait] Bekle
539
+ → waitMs: 2000
540
+
541
+ 3. [click] Retweet butonuna tikla
542
+ → selector: [data-testid="retweet"]
543
+
544
+ 4. [wait] Dropdown menu acilmasini bekle
545
+ → waitMs: 500
546
+
547
+ 5. [click] "Quote" secenegine tikla
548
+ → selector: [role="menuitem"]:nth-child(2)
549
+ → fallback: [role="menu"] [role="menuitem"]:has-text("Quote")
550
+
551
+ 6. [wait] Compose modal acilmasini bekle
552
+ → waitMs: 1000
553
+
554
+ 7. [type] Alinti metnini yaz
555
+ → selector: [data-testid="tweetTextarea_0"]
556
+ → value: {{QUOTE_TEXT}}
557
+
558
+ 8. [click] "Post" butonuna tikla
559
+ → selector: [data-testid="tweetButton"]
560
+ ```
561
+
562
+ **Alternatif yol (URL ile):**
563
+ ```
564
+ 1. [goto] https://x.com/compose/post?quote=TWEET_ID
565
+ 2. [wait] waitMs: 1500
566
+ 3. [type] [data-testid="tweetTextarea_0"] → {{QUOTE_TEXT}}
567
+ 4. [click] [data-testid="tweetButton"]
568
+ ```
569
+
570
+ ### 6.6 Yanit (Reply) Yazma
571
+
572
+ ```
573
+ 1. [goto] Tweet sayfasina git
574
+ → url: {{TWEET_URL}}
575
+
576
+ 2. [wait] Sayfa yuklenmesini bekle
577
+ → waitMs: 2000
578
+
579
+ 3. [click] Yanit butonuna tikla
580
+ → selector: [data-testid="reply"]
581
+ → fallback: [aria-label*="Reply"], [aria-label*="Yanitla"]
582
+
583
+ 4. [wait] Reply modal/alan acilmasini bekle
584
+ → waitMs: 1000
585
+ → Tweet detay sayfasinda reply alani asagida inline olarak acilir
586
+ → Timeline'da ise modal acilir
587
+
588
+ 5. [type] Yanit metnini yaz
589
+ → selector: [data-testid="tweetTextarea_0"]
590
+ → value: {{REPLY_TEXT}}
591
+
592
+ 6. [click] "Reply" / "Post" butonuna tikla
593
+ → selector: [data-testid="tweetButton"]
594
+ → fallback: [data-testid="tweetButtonInline"]
595
+ ```
596
+
597
+ **Tweet detay sayfasinda inline reply:**
598
+ ```
599
+ 1. [goto] {{TWEET_URL}}
600
+ 2. [wait] waitMs: 2000
601
+ 3. [click] Sayfadaki reply metin alanina tikla (tweet'in altinda)
602
+ → selector: [data-testid="tweetTextarea_0"]
603
+ 4. [type] Yaniti yaz → value: {{REPLY_TEXT}}
604
+ 5. [click] [data-testid="tweetButtonInline"]
605
+ ```
606
+
607
+ ### 6.7 Takip Etme (Follow)
608
+
609
+ **Profil sayfasindan:**
610
+ ```
611
+ 1. [goto] Kullanici profil sayfasina git
612
+ → url: https://x.com/{{USERNAME}}
613
+
614
+ 2. [wait] Sayfa yuklenmesini bekle
615
+ → waitMs: 2000
616
+
617
+ 3. [click] "Follow" butonuna tikla
618
+ → selector: [data-testid="{{USERNAME}}-follow"]
619
+ → fallback: [aria-label*="Follow @{{USERNAME}}"], [role="button"]:has-text("Follow")
620
+ → NOT: Eger zaten takip ediliyorsa buton "Following" yazar
621
+ ```
622
+
623
+ **Kullanici kartindan (who to follow, arama sonuclari):**
624
+ ```
625
+ 1. Kullanici kartini bul: [data-testid="UserCell"]
626
+ 2. Karttaki Follow butonuna tikla
627
+ → selector: [data-testid="UserCell"]:has-text("{{USERNAME}}") [role="button"]:has-text("Follow")
628
+ ```
629
+
630
+ ### 6.8 Takibi Birakma (Unfollow)
631
+
632
+ ```
633
+ 1. [goto] Kullanici profil sayfasina git
634
+ → url: https://x.com/{{USERNAME}}
635
+
636
+ 2. [wait] Sayfa yuklenmesini bekle
637
+ → waitMs: 2000
638
+
639
+ 3. [click] "Following" butonuna tikla (hover'da "Unfollow" olur)
640
+ → selector: [data-testid="{{USERNAME}}-unfollow"]
641
+ → fallback: [aria-label*="Following @{{USERNAME}}"], [role="button"]:has-text("Following")
642
+
643
+ 4. [wait] Onay dialogu acilmasini bekle
644
+ → waitMs: 500
645
+
646
+ 5. [click] "Unfollow" onay butonuna tikla
647
+ → selector: [data-testid="confirmationSheetConfirm"]
648
+ → fallback: [role="button"]:has-text("Unfollow"), button[data-testid="confirmationSheetConfirm"]
649
+ ```
650
+
651
+ ### 6.9 Engelleme (Block)
652
+
653
+ ```
654
+ 1. [goto] Kullanici profil sayfasina git
655
+ → url: https://x.com/{{USERNAME}}
656
+
657
+ 2. [wait] Bekle
658
+ → waitMs: 2000
659
+
660
+ 3. [click] Uc nokta menusune tikla
661
+ → selector: [data-testid="userActions"]
662
+ → fallback: [aria-label="More"]
663
+
664
+ 4. [wait] Menu acilmasini bekle
665
+ → waitMs: 500
666
+
667
+ 5. [click] "Block @username" secenegine tikla
668
+ → selector: [role="menuitem"]:has-text("Block")
669
+ → fallback: [role="menu"] [role="menuitem"]:has-text("Block")
670
+
671
+ 6. [wait] Onay dialogu
672
+ → waitMs: 500
673
+
674
+ 7. [click] Onay butonuna tikla
675
+ → selector: [data-testid="confirmationSheetConfirm"]
676
+ ```
677
+
678
+ ### 6.10 Sessize Alma (Mute)
679
+
680
+ ```
681
+ 1. [goto] https://x.com/{{USERNAME}}
682
+ 2. [wait] waitMs: 2000
683
+ 3. [click] [data-testid="userActions"]
684
+ 4. [wait] waitMs: 500
685
+ 5. [click] [role="menuitem"]:has-text("Mute")
686
+ → fallback: [role="menu"] [role="menuitem"]:has-text("Mute @")
687
+ ```
688
+
689
+ ### 6.11 Yer Imine Ekleme (Bookmark)
690
+
691
+ ```
692
+ 1. [goto] Tweet sayfasina git
693
+ → url: {{TWEET_URL}}
694
+ 2. [wait] waitMs: 2000
695
+ 3. [click] Yer imi butonuna tikla
696
+ → selector: [data-testid="bookmark"]
697
+ → fallback: [aria-label*="Bookmark"], [aria-label*="Yer imi"]
698
+ → NOT: Zaten yer imindeyse [data-testid="removeBookmark"] gorulur
699
+ ```
700
+
701
+ **Alternatif: Share menusu uzerinden:**
702
+ ```
703
+ 1. [click] [data-testid="share"] (ok butonu)
704
+ 2. [wait] waitMs: 500
705
+ 3. [click] [role="menuitem"]:has-text("Bookmark")
706
+ ```
707
+
708
+ ### 6.12 DM (Direkt Mesaj) Gonderme
709
+
710
+ **Mevcut konusmadan:**
711
+ ```
712
+ 1. [goto] Mesajlar sayfasina git
713
+ → url: https://x.com/messages
714
+
715
+ 2. [wait] Sayfa yuklenmesini bekle
716
+ → waitMs: 2000
717
+
718
+ 3. [click] Konusmayi sec
719
+ → selector: [data-testid="conversation"]:has-text("{{RECIPIENT}}")
720
+ → fallback: [data-testid="DM_Conversation_Avatar"]
721
+
722
+ 4. [wait] Konusma acilmasini bekle
723
+ → waitMs: 1000
724
+
725
+ 5. [click] Mesaj yazma alanina tikla
726
+ → selector: [data-testid="dmComposerTextInput"]
727
+ → fallback: [role="textbox"][data-testid="dmComposerTextInput"]
728
+
729
+ 6. [type] Mesaji yaz
730
+ → selector: [data-testid="dmComposerTextInput"]
731
+ → value: {{MESSAGE}}
732
+
733
+ 7. [click] Gonder butonuna tikla
734
+ → selector: [data-testid="dmComposerSendButton"]
735
+ → fallback: [aria-label="Send"], [aria-label="Gonder"]
736
+ ```
737
+
738
+ **Yeni konusma baslat:**
739
+ ```
740
+ 1. [goto] https://x.com/messages
741
+ 2. [wait] waitMs: 2000
742
+ 3. [click] Yeni mesaj butonu
743
+ → selector: [data-testid="newDirectMessage"]
744
+ → fallback: a[href="/messages/compose"], [aria-label*="New message"]
745
+ 4. [wait] waitMs: 1000
746
+ 5. [type] Alici ara
747
+ → selector: [data-testid="searchPeople"] veya input[aria-label*="Search"]
748
+ → value: {{RECIPIENT}}
749
+ 6. [wait] Sonuclarin yuklenmesini bekle
750
+ → waitMs: 1500
751
+ 7. [click] Sonuclardan kisiyi sec
752
+ → selector: [data-testid="typeaheadResult"]:first-child
753
+ → fallback: [role="option"]:first-child
754
+ 8. [click] "Next" / "Ileri" butonuna tikla
755
+ → selector: [data-testid="nextButton"]
756
+ → fallback: [role="button"]:has-text("Next")
757
+ 9. [type] Mesaji yaz
758
+ → selector: [data-testid="dmComposerTextInput"]
759
+ → value: {{MESSAGE}}
760
+ 10. [click] Gonder
761
+ → selector: [data-testid="dmComposerSendButton"]
762
+ ```
763
+
764
+ ### 6.13 Liste Olusturma
765
+
766
+ ```
767
+ 1. [goto] https://x.com/USERNAME/lists
768
+ 2. [wait] waitMs: 2000
769
+ 3. [click] Yeni liste butonuna tikla
770
+ → selector: [aria-label*="Create"]
771
+ → fallback: a[href="/i/lists/create"], [role="button"]:has-text("Create")
772
+ 4. [wait] waitMs: 1000
773
+ 5. [type] Liste adini yaz
774
+ → selector: input[name="name"]
775
+ → fallback: [placeholder*="Name"], input[aria-label*="Name"]
776
+ → value: {{LIST_NAME}}
777
+ 6. [type] Liste aciklamasini yaz (istege bagli)
778
+ → selector: textarea[name="description"]
779
+ → fallback: [placeholder*="Description"], textarea[aria-label*="Description"]
780
+ → value: {{LIST_DESCRIPTION}}
781
+ 7. [click] "Next" butonuna tikla
782
+ → selector: [role="button"]:has-text("Next")
783
+ 8. (Uye ekleme ekrani - istege bagli)
784
+ 9. [click] "Done" butonuna tikla
785
+ → selector: [role="button"]:has-text("Done")
786
+ ```
787
+
788
+ ### 6.14 Listeye Kisi Ekleme
789
+
790
+ ```
791
+ 1. [goto] https://x.com/i/lists/LIST_ID/members
792
+ 2. [wait] waitMs: 2000
793
+ 3. [click] Uye ekle butonuna tikla
794
+ → selector: [aria-label*="Add"]
795
+ 4. [type] Kullanici ara
796
+ → value: {{USERNAME}}
797
+ 5. [click] Sonuctan kisiyi sec
798
+ 6. [click] "Done" butonuna tikla
799
+ ```
800
+
801
+ ### 6.15 Arama Yapma
802
+
803
+ ```
804
+ 1. [click] Arama kutusuna tikla
805
+ → selector: [data-testid="SearchBox_Search_Input"]
806
+ → fallback: input[aria-label="Search query"], input[aria-label*="Ara"]
807
+ → NOT: Eger Explore sayfasinda degilsen, once Explore'a git
808
+
809
+ 2. [type] Arama terimini yaz
810
+ → selector: [data-testid="SearchBox_Search_Input"]
811
+ → value: {{SEARCH_QUERY}}
812
+
813
+ 3. [keypress] Enter'a bas
814
+ → key: Enter
815
+
816
+ 4. [wait] Sonuclarin yuklenmesini bekle
817
+ → waitMs: 2000
818
+ ```
819
+
820
+ **Filtreleme (arama sonuclarinda):**
821
+ ```
822
+ Sekme linkleri: [role="tab"] veya [data-testid="TabBarItemLink"]
823
+ - Top (varsayilan)
824
+ - Latest → &f=live
825
+ - People → &f=user
826
+ - Media → &f=media
827
+ - Lists → &f=list
828
+ ```
829
+
830
+ ### 6.16 Thread (Konu) Olusturma
831
+
832
+ ```
833
+ 1. [click] [data-testid="SideNav_NewTweet_Button"]
834
+ 2. [wait] waitMs: 1000
835
+ 3. [type] Ilk tweet metnini yaz
836
+ → selector: [data-testid="tweetTextarea_0"]
837
+ → value: {{CONTENT_1}}
838
+ 4. [click] Thread'e ekleme butonuna tikla (+)
839
+ → selector: [data-testid="addButton"]
840
+ → fallback: [aria-label*="Add another"]
841
+ 5. [type] Ikinci tweet metnini yaz
842
+ → selector: [data-testid="tweetTextarea_1"]
843
+ → value: {{CONTENT_2}}
844
+ 6. (Devam: daha fazla tweet eklenebilir, her biri tweetTextarea_N)
845
+ 7. [click] "Post all" butonuna tikla
846
+ → selector: [data-testid="tweetButton"]
847
+ → fallback: [role="button"]:has-text("Post all")
848
+ ```
849
+
850
+ ### 6.17 Tweet Silme
851
+
852
+ ```
853
+ 1. [goto] {{TWEET_URL}}
854
+ 2. [wait] waitMs: 2000
855
+ 3. [click] Uc nokta menusune tikla
856
+ → selector: [data-testid="caret"]
857
+ 4. [wait] waitMs: 500
858
+ 5. [click] "Delete" secenegine tikla
859
+ → selector: [role="menuitem"]:has-text("Delete")
860
+ → fallback: [role="menu"] [role="menuitem"]:has-text("Delete")
861
+ 6. [wait] waitMs: 500
862
+ 7. [click] Onay butonuna tikla
863
+ → selector: [data-testid="confirmationSheetConfirm"]
864
+ ```
865
+
866
+ ### 6.18 Tweet Sabitleme (Pin)
867
+
868
+ ```
869
+ 1. [goto] {{TWEET_URL}}
870
+ 2. [wait] waitMs: 2000
871
+ 3. [click] [data-testid="caret"]
872
+ 4. [wait] waitMs: 500
873
+ 5. [click] [role="menuitem"]:has-text("Pin to your profile")
874
+ 6. [wait] waitMs: 500
875
+ 7. [click] [data-testid="confirmationSheetConfirm"]
876
+ ```
877
+
878
+ ---
879
+
880
+ ## 7. Compose Dialog Detaylari
881
+
882
+ ### 7.1 contenteditable Div Yapisi
883
+
884
+ X, tweet yazma alani icin standart `<input>` veya `<textarea>` **KULLANMAZ**.
885
+ Bunun yerine `contenteditable="true"` ozelligi olan bir `<div>` kullanir.
886
+
887
+ ```html
888
+ <div data-testid="tweetTextarea_0"
889
+ contenteditable="true"
890
+ role="textbox"
891
+ aria-label="Post text"
892
+ aria-multiline="true"
893
+ tabindex="0"
894
+ class="..."
895
+ data-offset-key="...">
896
+ <div data-offset-key="...">
897
+ <span data-offset-key="...">
898
+ <span data-text="true">Metin buraya yazilir</span>
899
+ </span>
900
+ </div>
901
+ </div>
902
+ ```
903
+
904
+ **Playwright ile metin yazma stratejileri (oncelik sirasina gore):**
905
+
906
+ ```typescript
907
+ // Yontem 1: Tikla + keyboard.type (EN GUVENILIR)
908
+ await page.click('[data-testid="tweetTextarea_0"]');
909
+ await page.keyboard.type('Tweet metni', { delay: 50 });
910
+
911
+ // Yontem 2: fill (bazen calismayabilir contenteditable div'lerde)
912
+ await page.fill('[data-testid="tweetTextarea_0"]', 'Tweet metni');
913
+
914
+ // Yontem 3: type (bazen calismayabilir)
915
+ await page.type('[data-testid="tweetTextarea_0"]', 'Tweet metni', { delay: 50 });
916
+
917
+ // Yontem 4: Evaluate ile direkt DOM manipulasyonu (son care)
918
+ await page.evaluate(() => {
919
+ const el = document.querySelector('[data-testid="tweetTextarea_0"]');
920
+ el.textContent = 'Tweet metni';
921
+ el.dispatchEvent(new Event('input', { bubbles: true }));
922
+ });
923
+ ```
924
+
925
+ **Onemli notlar:**
926
+ - `keyboard.type()` kullanirken `delay: 30-80` ms arasi gecikme ekle (daha dogal)
927
+ - Metin yazildiktan sonra 300-500ms bekle ki X, "Post" butonunu aktif etsin
928
+ - Emoji icin: `keyboard.type()` dogrudan Unicode emoji'yi yazabilir
929
+ - Hashtag icin: `#` karakteri normal sekilde yazilabilir
930
+ - Mention icin: `@` yazilinca autocomplete acilir, secim yapilmali veya devam edilmeli
931
+
932
+ ### 7.2 Medya Yukleme Akisi
933
+
934
+ ```
935
+ 1. Compose modal acik durumda olmali
936
+ 2. Gizli file input'a dosya set et:
937
+ → page.setInputFiles('[data-testid="fileInput"]', dosyaYolu)
938
+ → Birden fazla dosya: page.setInputFiles('[data-testid="fileInput"]', [dosya1, dosya2])
939
+ 3. Yukleme tamamlaninca [data-testid="attachments"] gorulur
940
+ 4. Her gorsel uzerinde [data-testid="removeMedia"] ile kaldirilabilir
941
+ 5. Alt text eklemek icin gorsel uzerine tikla → "Add description" / "Alt" butonu
942
+ ```
943
+
944
+ **Desteklenen formatlar:**
945
+ - Gorsel: JPEG, PNG, GIF, WebP
946
+ - Video: MP4, MOV
947
+ - GIF: Animasyonlu GIF (5MB'a kadar gorsel, 15MB'a kadar GIF)
948
+ - Video: 512MB'a kadar (Premium ile 8GB, 4 saate kadar)
949
+
950
+ **Gorsel limitleri:**
951
+ - Tek tweet'te en fazla **4 gorsel** VEYA **1 video** VEYA **1 GIF**
952
+ - Gorsel ve video birlestirilemez
953
+
954
+ ### 7.3 Anket (Poll) Olusturma
955
+
956
+ ```
957
+ 1. Compose modal acik durumda
958
+ 2. [click] Anket butonuna tikla
959
+ → selector: [aria-label*="Poll"], toolbar icindeki bar chart ikonu
960
+ 3. [type] Ilk secenek
961
+ → selector: input[placeholder*="Choice 1"]
962
+ → value: {{OPTION_1}}
963
+ 4. [type] Ikinci secenek
964
+ → selector: input[placeholder*="Choice 2"]
965
+ → value: {{OPTION_2}}
966
+ 5. (istege bagli) 3. ve 4. secenekler icin "+" butonu
967
+ 6. Anket suresi secimi: 1-7 gun, saat ve dakika dropdown'lari
968
+ 7. [click] [data-testid="tweetButton"]
969
+ ```
970
+
971
+ ### 7.4 Zamanlanmis Tweet
972
+
973
+ ```
974
+ 1. Compose modal acik durumda
975
+ 2. [type] Tweet metnini yaz
976
+ 3. [click] Takvim ikonuna tikla
977
+ → selector: [data-testid="scheduledButton"]
978
+ → fallback: [aria-label*="Schedule"]
979
+ 4. Tarih ve saat sec (date picker)
980
+ 5. [click] "Schedule" / "Zamanla" butonuna tikla
981
+ → selector: [data-testid="scheduledConfirmationPrimaryAction"]
982
+ → fallback: [role="button"]:has-text("Schedule")
983
+ ```
984
+
985
+ ### 7.5 Yanit Kisitlamalari
986
+
987
+ Compose modal'da "Everyone can reply" dropdown'u:
988
+ ```
989
+ 1. [click] "Everyone can reply" metnine tikla
990
+ → selector: [data-testid="Dropdown"]
991
+ → fallback: [aria-label*="Everyone can reply"]
992
+ 2. Secenekler:
993
+ - "Everyone" → Herkes yanitlayabilir
994
+ - "Accounts you follow" → Sadece takip ettiklerim
995
+ - "Verified accounts" → Sadece dogrulanmis hesaplar
996
+ - "Only accounts you mention" → Sadece bahsettigin kisiler
997
+ ```
998
+
999
+ ---
1000
+
1001
+ ## 8. Gorsel ve Video Boyutlari
1002
+
1003
+ ### 8.1 Post Gorselleri
1004
+
1005
+ | Tur | Boyut | Oran | Aciklama |
1006
+ |-----|-------|------|----------|
1007
+ | Tek gorsel (yatay) | 1200 x 675 px | 16:9 | Ideal timeline gorunumu |
1008
+ | Tek gorsel (kare) | 1080 x 1080 px | 1:1 | Kare format |
1009
+ | Tek gorsel (dikey) | 1080 x 1350 px | 4:5 | Dikey/portrait |
1010
+ | Iki gorsel | 700 x 800 px (her biri) | 7:8 | Yan yana gorunur |
1011
+ | Uc gorsel | 1 buyuk (sol) + 2 kucuk (sag) | - | Asimetrik duzenleme |
1012
+ | Dort gorsel | 600 x 335 px (her biri) | 16:9 | 2x2 grid |
1013
+ | GIF | 1280 x 1080 px | - | Otomatik oynar |
1014
+
1015
+ ### 8.2 Profil Gorselleri
1016
+
1017
+ | Tur | Boyut | Oran | Aciklama |
1018
+ |-----|-------|------|----------|
1019
+ | Profil fotosu | 400 x 400 px | 1:1 | Yuvarlak kirilir, PNG/JPG, maks 2MB |
1020
+ | Kapak fotosu | 1500 x 500 px | 3:1 | Header banner, maks 5MB |
1021
+
1022
+ ### 8.3 Video Spesifikasyonlari
1023
+
1024
+ | Ozellik | Deger |
1025
+ |---------|-------|
1026
+ | Format | MP4 (H.264 codec) |
1027
+ | Maks boyut | 512 MB (standar), 8 GB (Premium+) |
1028
+ | Maks sure | 2 dk 20 sn (standart), 4 saat (Premium+) |
1029
+ | Cozunurluk | 1920x1200 veya 1200x1920 (maks) |
1030
+ | Min cozunurluk | 32x32 |
1031
+ | Kare hizi | 40 fps (maks) |
1032
+ | Bit hizi | 25 Mbps (maks) |
1033
+
1034
+ ### 8.4 Link Onizleme Karti (Card) Boyutlari
1035
+
1036
+ | Tur | Boyut | Aciklama |
1037
+ |-----|-------|----------|
1038
+ | Summary card | 120 x 120 px | Kucuk kare gorsel |
1039
+ | Summary large image | 1200 x 628 px | Buyuk gorsel, 16:9'a yakin |
1040
+ | Player card | 1200 x 675 px | Video/medya player |
1041
+
1042
+ ---
1043
+
1044
+ ## 9. Rate Limiting ve Anti-Bot Onlemleri
1045
+
1046
+ ### 9.1 Bilinen Rate Limit'ler
1047
+
1048
+ | Aksiyon | Limit | Periyot | Not |
1049
+ |---------|-------|---------|-----|
1050
+ | Tweet atma | ~2400 tweet | 24 saat | Gunluk limit |
1051
+ | Begeni | ~1000 begeni | 24 saat | Yukseltilebilir |
1052
+ | Takip etme | ~400 follow | 24 saat | Yeni hesaplarda daha az |
1053
+ | DM gonderme | ~500 mesaj | 24 saat | Hesap yasina bagli |
1054
+ | Retweet | ~300 retweet | 3 saat | Tahmine dayali |
1055
+ | Arama | ~180 arama | 15 dakika | API limiti, browser'da daha yumusak |
1056
+ | Profil goruntulemee | ~500 profil | 15 dakika | Tahmine dayali |
1057
+ | Liste olusturma | ~1000 liste | Hesap basina | Toplam limit |
1058
+ | Liste uyesi | ~5000 uye | Liste basina | Toplam limit |
1059
+ | Takip limiti | ~5000 kisi | Hesap basina | Takipci/takip oraniyla artar |
1060
+
1061
+ ### 9.2 Anti-Bot Algilama Yontemleri
1062
+
1063
+ X su yontemlerle bot algilamasi yapar:
1064
+
1065
+ 1. **navigator.webdriver kontrolu**
1066
+ - Playwright/Puppeteer varsayilan olarak `navigator.webdriver = true` yapar
1067
+ - Cozum: `--disable-blink-features=AutomationControlled` flag'i
1068
+ - CDP ile: `Page.addScriptToEvaluateOnNewDocument` ile override et
1069
+
1070
+ 2. **Automation flag'leri**
1071
+ - `window.chrome.runtime` kontrolu
1072
+ - `navigator.plugins` uzunlugu kontrolu
1073
+ - Cozum: Gercek Chrome profili kullan (bu proje bunu yapiyor)
1074
+
1075
+ 3. **Davranis analizi**
1076
+ - Cok hizli tiklamalar (insan gibi degilse)
1077
+ - Duzensiz mouse hareketi yoklugu
1078
+ - Sabit aralikli aksiyonlar (bot gibi)
1079
+ - Her seferinde ayni akis
1080
+
1081
+ 4. **Fingerprinting**
1082
+ - Canvas fingerprint
1083
+ - WebGL fingerprint
1084
+ - Audio context fingerprint
1085
+ - Font enumerasyonu
1086
+
1087
+ 5. **IP ve Session kontrolleri**
1088
+ - Ayni IP'den cok fazla hesap
1089
+ - VPN/proxy algilama
1090
+ - Session suresinin anormal kisaligi
1091
+
1092
+ ### 9.3 Guvenli Gecikme Sureleri
1093
+
1094
+ Bot algilanmasini onlemek icin onerilir gecikmeler:
1095
+
1096
+ | Aksiyon | Min Gecikme | Ideal Gecikme | Aciklama |
1097
+ |---------|-------------|---------------|----------|
1098
+ | Sayfa yukleme sonrasi | 2000 ms | 3000-5000 ms | Sayfanin tam yuklenmesi |
1099
+ | Tiklamalar arasi | 500 ms | 1000-3000 ms | Rastgele degisim ekle |
1100
+ | Metin yazma (harf basi) | 30 ms | 50-120 ms | Insan yazim hizi |
1101
+ | Begeni islemleri arasi | 3000 ms | 5000-15000 ms | Art arda begeni suspicious |
1102
+ | Takip islemleri arasi | 5000 ms | 10000-30000 ms | En riskli aksiyon |
1103
+ | Retweet islemleri arasi | 3000 ms | 8000-20000 ms | Orta risk |
1104
+ | Post islemleri arasi | 30000 ms | 60000-180000 ms | Tweet aralari |
1105
+ | Arama islemleri arasi | 2000 ms | 5000-10000 ms | Art arda arama |
1106
+ | Sayfa gecisleri arasi | 1000 ms | 2000-5000 ms | Navigasyon |
1107
+ | DM gonderme arasi | 3000 ms | 5000-15000 ms | Spam filtresi hassas |
1108
+
1109
+ **Rastgele gecikme formulu:**
1110
+ ```
1111
+ gercekGecikme = idealGecikme + (Math.random() * idealGecikme * 0.5) - (idealGecikme * 0.25)
1112
+ ```
1113
+ Bu, ideal gecikmenin %75 ile %125 arasi bir deger uretir.
1114
+
1115
+ ### 9.4 Guvenli Otomasyon Pratikleri
1116
+
1117
+ 1. **Gercek Chrome profili kullan** (bu proje bunu yapiyor - en onemli onlem)
1118
+ 2. **Mouse hareketleri ekle** - Tiklamadan once mouse'u hedefe dogal sekilde hareket ettir
1119
+ 3. **Scroll davranisi** - Sayfayi biraz scroll et, tum icerigi gorme
1120
+ 4. **Session suresi** - Tek seferde 30 dk'dan fazla islem yapma
1121
+ 5. **Gunluk limit** - Toplu islemleri gunlere yay
1122
+ 6. **Farkli akislar** - Her seferinde biraz farkli sirayla islem yap
1123
+ 7. **Ara verme** - 20-30 islemden sonra 5-15 dk ara ver
1124
+ 8. **Organik davranis** - Arada timeline scroll et, profil ziyaret et
1125
+ 9. **Captcha/Challenge** - Challenge cikarsa dur, kullaniciya bildir
1126
+ 10. **Tek hesap** - Ayni tarayicidan tek hesap kullan
1127
+
1128
+ ### 9.5 Challenge/Captcha Tespit
1129
+
1130
+ X bazen guvenlik challenge'i cikarabilir:
1131
+
1132
+ ```
1133
+ Tespit selectorleri:
1134
+ - [data-testid="OCF_CallToAction_Button"] → Challenge butonu
1135
+ - [id="arkose_iframe"] → Arkose Labs captcha
1136
+ - iframe[title*="challenge"] → Challenge iframe
1137
+ - div:has-text("Verify your identity") → Dogrulama ekrani
1138
+ - div:has-text("Unusual login activity") → Anormal giris uyarisi
1139
+ - [data-testid="BottomBar"] → Cookie/izin cubugu
1140
+ ```
1141
+
1142
+ Challenge algilandiginda:
1143
+ 1. Islemleri durdur
1144
+ 2. Screenshot al
1145
+ 3. Kullaniciya bildir
1146
+ 4. Kullanici elle cozdukten sonra devam et
1147
+
1148
+ ---
1149
+
1150
+ ## 10. Onemli CSS Class Kaliplari
1151
+
1152
+ X, dinamik class isimleri kullanir (r-XXXX formati). Bunlar GUVENILIR DEGILDIR
1153
+ ve her build'de degisebilir. Asagidakiler referans amaçlidir:
1154
+
1155
+ ```css
1156
+ /* Guvenilir olmayan ama yaygin gorulen class kaliplari */
1157
+ .r-1habvwh /* Buyuk yazi (baslık) */
1158
+ .r-1h0z5md /* Kucuk yazi */
1159
+ .r-8akbif /* Mavi renk (link, buton) */
1160
+ .r-urgr8i /* Kirmizi renk (unlike) */
1161
+ .r-1bwzh9t /* Yesil renk */
1162
+ .css-175oi2r /* Genel container */
1163
+ .css-1jxf684 /* Metin elemani */
1164
+ ```
1165
+
1166
+ **KURAL: CSS class'larina ASLA guvenme. Her zaman data-testid, aria-label, role kullan.**
1167
+
1168
+ ---
1169
+
1170
+ ## 11. Sayfa Yukleme ve Bekleme Stratejileri
1171
+
1172
+ ### 11.1 Sayfa Hazir Sinyalleri
1173
+
1174
+ ```
1175
+ Tweet yuklendi mi?
1176
+ → [data-testid="tweet"] elementinin varligini kontrol et
1177
+ → Fallback: [data-testid="cellInnerDiv"] sayisi > 0
1178
+
1179
+ Profil yuklendi mi?
1180
+ → [data-testid="UserName"] elementinin varligini kontrol et
1181
+ → Fallback: [data-testid="UserDescription"] var mi
1182
+
1183
+ Compose modal acildi mi?
1184
+ → [data-testid="tweetTextarea_0"] elementinin varligini kontrol et
1185
+ → Fallback: [role="dialog"] icinde [role="textbox"] var mi
1186
+
1187
+ Arama sonuclari yuklendi mi?
1188
+ → [data-testid="tweet"] veya [data-testid="UserCell"] var mi
1189
+ → Fallback: [data-testid="emptyState"] yok mu (sonuc yoksa bu gorulur)
1190
+
1191
+ Timeline yuklendi mi?
1192
+ → [data-testid="primaryColumn"] icinde [data-testid="cellInnerDiv"] var mi
1193
+ → Progress bar kaybolmus mu: [role="progressbar"] yok mu
1194
+
1195
+ Islem basarili mi?
1196
+ → [data-testid="toast"] ile basari mesaji gorulur mu
1197
+ → "Your post was sent" / "Tweet was sent" gibi mesajlar
1198
+ ```
1199
+
1200
+ ### 11.2 Playwright Bekleme Ornekleri
1201
+
1202
+ ```typescript
1203
+ // Element gorulene kadar bekle
1204
+ await page.waitForSelector('[data-testid="tweet"]', { timeout: 10000 });
1205
+
1206
+ // Element kaybolana kadar bekle
1207
+ await page.waitForSelector('[role="progressbar"]', { state: 'hidden', timeout: 10000 });
1208
+
1209
+ // Network idle bekle
1210
+ await page.waitForLoadState('networkidle');
1211
+
1212
+ // Belirli URL'ye navigasyon bekle
1213
+ await page.waitForURL('**/home');
1214
+ ```
1215
+
1216
+ ---
1217
+
1218
+ ## 12. Bilinen Sorunlar ve Cozumler
1219
+
1220
+ ### 12.1 Compose Alani contenteditable Sorunu
1221
+
1222
+ **Sorun:** `page.fill()` veya `page.type()` contenteditable div'lerde calismayabilir.
1223
+ **Cozum:** Tikla + `keyboard.type()` yontemi:
1224
+ ```typescript
1225
+ await page.click('[data-testid="tweetTextarea_0"]');
1226
+ await page.waitForTimeout(300);
1227
+ await page.keyboard.type('Metin', { delay: 50 });
1228
+ ```
1229
+
1230
+ ### 12.2 Retweet Dropdown Menusu
1231
+
1232
+ **Sorun:** Retweet butonuna tiklamak direkt retweet yapmaz, menu acar.
1233
+ **Cozum:** Menu acildiktan sonra "Repost" secenegine tikla:
1234
+ ```typescript
1235
+ await page.click('[data-testid="retweet"]');
1236
+ await page.waitForSelector('[role="menu"]', { timeout: 3000 });
1237
+ await page.click('[data-testid="retweetConfirm"]');
1238
+ ```
1239
+
1240
+ ### 12.3 Following Butonu Hover Durumu
1241
+
1242
+ **Sorun:** "Following" butonu hover olmadan "Unfollow" metnini gostermez.
1243
+ **Cozum:** Hover simule et veya direkt tikla:
1244
+ ```typescript
1245
+ await page.hover('[data-testid="USERNAME-unfollow"]');
1246
+ await page.waitForTimeout(300);
1247
+ await page.click('[data-testid="USERNAME-unfollow"]');
1248
+ ```
1249
+
1250
+ ### 12.4 Lazy Loading ve Sonsuz Scroll
1251
+
1252
+ **Sorun:** Timeline'daki tweetler lazy load edilir, scroll gerekir.
1253
+ **Cozum:** Belirli bir tweet'i bulmak icin scroll et:
1254
+ ```typescript
1255
+ while (true) {
1256
+ const tweet = await page.$('article:has-text("aranan metin")');
1257
+ if (tweet) break;
1258
+ await page.evaluate(() => window.scrollBy(0, 800));
1259
+ await page.waitForTimeout(1000);
1260
+ }
1261
+ ```
1262
+
1263
+ ### 12.5 Cookie Banner / Izin Dialoglari
1264
+
1265
+ **Sorun:** Ilk ziyarette cookie banner cikar.
1266
+ **Cozum:** Varsa kapat:
1267
+ ```typescript
1268
+ const cookieBtn = await page.$('[data-testid="BottomBar"] [role="button"]');
1269
+ if (cookieBtn) await cookieBtn.click();
1270
+ ```
1271
+
1272
+ ### 12.6 "Post" Butonu Disabled Durumu
1273
+
1274
+ **Sorun:** Metin alanina icerik yazilmadan "Post" butonu disabled.
1275
+ **Cozum:** Metin yazdiktan sonra 300-500ms bekle, butonun aktif olmasini kontrol et:
1276
+ ```typescript
1277
+ await page.keyboard.type('Metin', { delay: 50 });
1278
+ await page.waitForTimeout(500);
1279
+ await page.waitForSelector('[data-testid="tweetButton"]:not([aria-disabled="true"])');
1280
+ await page.click('[data-testid="tweetButton"]');
1281
+ ```
1282
+
1283
+ ### 12.7 Login Redirect
1284
+
1285
+ **Sorun:** Giris yapilmamissa X, login sayfasina yonlendirir.
1286
+ **Tespit:**
1287
+ ```
1288
+ URL: https://x.com/i/flow/login
1289
+ veya
1290
+ URL: https://x.com/login
1291
+ ```
1292
+ **Cozum:** Bu proje gercek Chrome profili kullanir, dolayisiyla login zaten yapilmis olmali.
1293
+
1294
+ ---
1295
+
1296
+ ## 13. X Premium (Eski Twitter Blue) Farklari
1297
+
1298
+ | Ozellik | Ucretsiz | Premium | Premium+ |
1299
+ |---------|----------|---------|----------|
1300
+ | Tweet uzunlugu | 280 karakter | 25.000 karakter | 25.000 karakter |
1301
+ | Video suresi | 2 dk 20 sn | 3 saat | 4 saat |
1302
+ | Video boyutu | 512 MB | 8 GB | 8 GB |
1303
+ | Tweet duzenleme | Yok | 30 dk icinde 5 kez | 30 dk icinde 5 kez |
1304
+ | Yer imi klasorleri | Yok | Var | Var |
1305
+ | Uzun tweet okuma | Kisitli | Sinrsiz | Sinrsiz |
1306
+ | Grok AI | Sinirli | Var | Gelismis |
1307
+
1308
+ ---
1309
+
1310
+ ## 14. Keyboard Shortcut'lar
1311
+
1312
+ X platformunda kullanilabilecek klavye kisayollari:
1313
+
1314
+ | Kisayol | Aksiyon |
1315
+ |---------|---------|
1316
+ | `n` | Yeni tweet compose acar |
1317
+ | `l` | Secili tweet'i begen |
1318
+ | `r` | Secili tweet'e yanit |
1319
+ | `t` | Secili tweet'i retweet |
1320
+ | `s` | Secili tweet'i yer imlerine ekle |
1321
+ | `u` | Secili tweet'i sessize al |
1322
+ | `b` | Secili tweet'i engelle |
1323
+ | `Enter` | Tweet detayini ac |
1324
+ | `j` | Sonraki tweet |
1325
+ | `k` | Onceki tweet |
1326
+ | `.` | Timeline'i yenile |
1327
+ | `/` | Arama kutusuna fokus |
1328
+ | `g + h` | Ana sayfaya git |
1329
+ | `g + e` | Kesfet'e git |
1330
+ | `g + n` | Bildirimlere git |
1331
+ | `g + m` | Mesajlara git |
1332
+ | `g + p` | Profile git |
1333
+ | `g + l` | Begeni sayfasina git |
1334
+ | `g + i` | Listeler sayfasina git |
1335
+ | `?` | Kisayollari goster |
1336
+ | `Esc` | Modal/dialog kapat |
1337
+
1338
+ **Otomasyon icin kisayol kullanimi:**
1339
+ ```typescript
1340
+ // Yeni tweet acmak icin 'n' tusu
1341
+ await page.keyboard.press('n');
1342
+ await page.waitForSelector('[data-testid="tweetTextarea_0"]');
1343
+
1344
+ // Tweet begenme icin 'l' tusu (tweet secili olmali)
1345
+ await page.keyboard.press('l');
1346
+ ```
1347
+
1348
+ ---
1349
+
1350
+ ## 15. Tweet Icerigindeki Ozel Elementler
1351
+
1352
+ ### Mention (@kullanici)
1353
+
1354
+ Compose alaninda `@` yazildiginda autocomplete acilir:
1355
+ ```
1356
+ - Autocomplete container: [data-testid="Typeahead"]
1357
+ - Sonuc elemani: [data-testid="typeaheadResult"]
1358
+ - Secim: tikla veya Enter
1359
+ - Kapatma: Escape
1360
+ ```
1361
+
1362
+ ### Hashtag (#konu)
1363
+
1364
+ `#` yazildiginda autocomplete acilir (trending hashtag'ler):
1365
+ ```
1366
+ - Autocomplete container: [data-testid="Typeahead"]
1367
+ - Sonuc elemani: [data-testid="typeaheadResult"]
1368
+ ```
1369
+
1370
+ ### Emoji
1371
+
1372
+ ```
1373
+ - Emoji butonu: [data-testid="emojiButton"] (compose toolbar'da)
1374
+ - Emoji picker: [data-testid="Dropdown"] icinde
1375
+ - Emoji arama: Picker icindeki input alani
1376
+ - Alternatif: keyboard.type() ile dogrudan emoji yazilabilir (orn: keyboard.type('😀'))
1377
+ ```
1378
+
1379
+ ### URL/Link
1380
+
1381
+ - URL'ler otomatik olarak kisaltilir (t.co)
1382
+ - Link preview karti otomatik olusur
1383
+ - Karakter limiti icinde URL kisaltilmis halini sayar (23 karakter)
1384
+
1385
+ ---
1386
+
1387
+ ## 16. Hata Kodlari ve Anlamlari
1388
+
1389
+ | Mesaj / Durum | Anlam | Cozum |
1390
+ |---------------|-------|-------|
1391
+ | "Something went wrong" | Genel hata | Sayfayi yenile, tekrar dene |
1392
+ | "Rate limit exceeded" | Aksiyon limiti asildi | 15-60 dk bekle |
1393
+ | "You are unable to..." | Yetki/kisitlama | Engellenmis olabilir |
1394
+ | "This Tweet was deleted" | Tweet silinmis | Farkli tweet sec |
1395
+ | "Account suspended" | Hesap askiya alinmis | Farkli hesap kullan |
1396
+ | "Restricted account" | Hesap kisitlanmis | Elle dogrulama gerekli |
1397
+ | "Could not authenticate" | Oturum sona ermis | Tekrar login |
1398
+ | Toast: "You already sent this" | Ayni tweet tekrar | Icerik degistir |
1399
+ | "Over capacity" | X asiri yuklu | 5-10 dk bekle |
1400
+
1401
+ ---
1402
+
1403
+ ## 17. Zamanlama ve Cron Bilgileri
1404
+
1405
+ ### En Iyi Post Zamanlari (Turkiye Saati - UTC+3)
1406
+
1407
+ | Gun | Ideal Saat | Aciklama |
1408
+ |-----|-----------|----------|
1409
+ | Pazartesi | 08:00-10:00, 18:00-20:00 | Is baslangici ve bitis |
1410
+ | Sali | 09:00-11:00, 19:00-21:00 | En aktif gunlerden |
1411
+ | Carsamba | 09:00-11:00, 18:00-20:00 | Orta hafta dorugu |
1412
+ | Persembe | 09:00-11:00, 19:00-21:00 | Yuksek etkilesim |
1413
+ | Cuma | 09:00-11:00, 17:00-19:00 | Erken bitis etkisi |
1414
+ | Cumartesi | 10:00-12:00 | Hafta sonu yavaslar |
1415
+ | Pazar | 17:00-20:00 | Aksam saatleri daha iyi |
1416
+
1417
+ ---
1418
+
1419
+ ## 18. Tweet Detay Sayfasi DOM Yapisi
1420
+
1421
+ Tek bir tweet'in (`[data-testid="tweet"]`) icindeki hiyerarsi:
1422
+
1423
+ ```
1424
+ article[data-testid="tweet"][role="article"]
1425
+ ├── div (avatar bolumu)
1426
+ │ └── [data-testid="UserAvatar-Container-USERNAME"]
1427
+ │ └── img (profil gorseli)
1428
+ ├── div (icerik bolumu)
1429
+ │ ├── div (header: kullanici bilgileri)
1430
+ │ │ ├── [data-testid="User-Name"]
1431
+ │ │ │ ├── span (gorunen ad)
1432
+ │ │ │ └── span (@username)
1433
+ │ │ ├── span (tarih/saat)
1434
+ │ │ └── [data-testid="caret"] (uc nokta menu)
1435
+ │ ├── div (tweet metni)
1436
+ │ │ └── [data-testid="tweetText"]
1437
+ │ │ └── span (metin icerigi)
1438
+ │ ├── div (medya alani - varsa)
1439
+ │ │ └── [data-testid="tweetPhoto"] veya [data-testid="videoPlayer"]
1440
+ │ ├── div (link karti - varsa)
1441
+ │ │ └── [data-testid="card.wrapper"]
1442
+ │ └── div (aksiyon butonlari)
1443
+ │ ├── [data-testid="reply"] + span (sayi)
1444
+ │ ├── [data-testid="retweet"] + span (sayi)
1445
+ │ ├── [data-testid="like"] + span (sayi)
1446
+ │ ├── [data-testid="bookmark"]
1447
+ │ └── [data-testid="share"]
1448
+ └── [data-testid="socialContext"] (varsa: "X liked", "X retweeted")
1449
+ ```
1450
+
1451
+ ---
1452
+
1453
+ ## 19. Responsive Breakpoint'ler
1454
+
1455
+ | Genislik | Gorunum | Degisiklik |
1456
+ |----------|---------|------------|
1457
+ | > 1280px | Tam gorunum | Sol sidebar + Ana icerik + Sag sidebar |
1458
+ | 1005-1280px | Orta | Sol sidebar darali (sadece ikonlar) |
1459
+ | 688-1004px | Dar | Sag sidebar kaybolur |
1460
+ | < 688px | Mobil | Sol sidebar alt cubuk olur |
1461
+
1462
+ **Otomasyon icin oneri:** Tarayici penceresini en az 1300px genislikte ac ki tum elementler gorunsun.
1463
+
1464
+ ```typescript
1465
+ await page.setViewportSize({ width: 1440, height: 900 });
1466
+ ```
1467
+
1468
+ ---
1469
+
1470
+ ## 20. X API vs Browser Otomasyon Karsilastirmasi
1471
+
1472
+ Bu proje browser otomasyonu kullanir. API kullanmaz. Nedenler:
1473
+
1474
+ | Ozellik | API | Browser Otomasyon |
1475
+ |---------|-----|-------------------|
1476
+ | Maliyet | Ucretli (Essential: $100/ay) | Ucretsiz |
1477
+ | Rate limit | Cok katı | Daha esnek |
1478
+ | Begeni/RT | API v2 ile sinirli | Sorunsuz |
1479
+ | DM | API ile kisitli | Sorunsuz |
1480
+ | Gorsel | API ile mumkun | Sorunsuz |
1481
+ | Bot algilama | Dusuk (resmi API) | Orta-yuksek risk |
1482
+ | Guvenilirlik | Yuksek | UI degisimlerine duyarli |
1483
+ | Kurulum | Token/OAuth gerekli | Sadece Chrome login |
1484
+
1485
+ ---
1486
+
1487
+ ## 21. Selector Oncelik Sirasi
1488
+
1489
+ AI mapper selector secerken su oncelik sirasini takip etmeli:
1490
+
1491
+ 1. **`data-testid`** - En guvenilir, nadiren degisir
1492
+ 2. **`aria-label`** - Erisilebilirlik attribute'u, dile bagli
1493
+ 3. **`role` + icerik kombinasyonu** - `[role="button"]:has-text("Follow")`
1494
+ 4. **`id`** - Varsa guvenilir ama X'te nadir
1495
+ 5. **`name`** - Form elementlerinde
1496
+ 6. **Yapisal selector** - `article > div > div:nth-child(2)` (SON CARE, kiriilgan)
1497
+ 7. **CSS class** - ASLA KULLANMA (her build'de degisir)
1498
+
1499
+ ---
1500
+
1501
+ ## 22. Coklu Sekme ve Pencere Yonetimi
1502
+
1503
+ X bazi aksiyonlarda yeni sekme/pencere acar:
1504
+
1505
+ - Share butonundan "Copy link" → Clipboard'a kopyalar (yeni sekme yok)
1506
+ - Share butonundan "Share via..." → Platform secimi
1507
+ - DM'den link tiklamak → Yeni sekmede acilir
1508
+ - Profildeki web sitesi linki → Yeni sekmede acilir
1509
+
1510
+ **Yeni sekme algilama:**
1511
+ ```typescript
1512
+ const [newPage] = await Promise.all([
1513
+ context.waitForEvent('page'),
1514
+ page.click('link-selector')
1515
+ ]);
1516
+ await newPage.waitForLoadState();
1517
+ ```
1518
+
1519
+ ---
1520
+
1521
+ ## 23. Login Sonrasi Olasi Ekranlar
1522
+
1523
+ Ilk giris sonrasi su ekranlar ciikabilir:
1524
+
1525
+ 1. **Cookie consent banner** → Kapat veya kabul et
1526
+ 2. **"Turn on notifications"** popup → "Not now" / "Allow"
1527
+ 3. **"Who to follow"** onerileri → Skip veya takip et
1528
+ 4. **"What are you interested in?"** → Konu secimi, skip edilebilir
1529
+ 5. **Phone/email verification** → Dogrulama gerekli
1530
+ 6. **"Your account has been locked"** → Captcha/dogrulama
1531
+
1532
+ Bu ekranlardan herhangi biri cikarsa, AI heal mekanizmasi ekrani analiz edip uygun aksiyonu almali.