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/README.md +226 -0
- package/bin/postinstall.js +19 -0
- package/bin/social-agent.js +109 -0
- package/config.example.json +20 -0
- package/hooks/post-push +69 -0
- package/knowledge/bluesky.md +1083 -0
- package/knowledge/facebook.md +603 -0
- package/knowledge/instagram.md +686 -0
- package/knowledge/linkedin.md +1013 -0
- package/knowledge/mastodon.md +1291 -0
- package/knowledge/telegram.md +824 -0
- package/knowledge/x.md +1532 -0
- package/package.json +30 -0
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.
|