# Twitter Element Features and Positioning Reference

This document provides technical details about Twitter/X platform DOM structure, element features, selector stability, etc., for reference during material collection and video recording.

---

## Table of Contents

- [Element Feature Recording](#element-feature-recording)
- [scroll_to Text Positioning](#scroll_to-text-positioning)
- [Selector Stability Analysis](#selector-stability-analysis)
- [Common Issues and Solutions](#common-issues-and-solutions)

---

## Element Feature Recording

### Why Element Features Are Needed

Twitter uses virtual list rendering, with DOM elements dynamically created/destroyed. Traditional CSS selectors (like `.css-abc123`) are extremely unstable.

**Recommended Approach**: Record unique text fragments as features, then locate elements via text search later.

### Recording Format

```json
{
  "tweet_url": "https://x.com/user/status/123456",
  "element_feature": "AI will change the way we work, but we need",
  "feature_type": "text_content",
  "context": {
    "author": "@username",
    "is_comment": false,
    "comment_depth": 0
  }
}
```

### Feature Selection Principles

1. **Uniqueness**: Select text fragments that appear uniquely on the page
2. **Stability**: Avoid including dynamic content (like timestamps, numbers)
3. **Sufficient Length**: At least 10 characters, recommend 15-25 characters
4. **Complete Words**: Don't truncate in the middle of words

**Good Features**:
```
✅ "AI will change the way we work, but we need"
✅ "I completely disagree with this view because"
✅ "The future of programming is"
```

**Bad Features**:
```
❌ "AI"  // Too short, not unique
❌ "2.3K likes"  // Contains dynamic numbers
❌ "12:30 PM"  // Timestamp
❌ "way we wo"  // Truncated in middle of word
```

---

## scroll_to Text Positioning

### Basic Usage

```bash
# Scroll to element containing specified text
uv run frago scroll-to "AI will change the way we work"
```

### Usage in Storyboard Scripts

```json
{
  "action": "scroll_to",
  "text": "AI will change the way we work, but we need",
  "wait": 1.5
}
```

### Handling Positioning Failures

When `scroll_to` cannot find an element:

1. **Check text accuracy**: Copy original text to avoid typos
2. **Try longer fragments**: Increase feature text length
3. **Use fallback positioning**:
   ```json
   {
     "action": "scroll_to",
     "text": "fallback text fragment",
     "fallback": {
       "action": "scroll",
       "direction": "down",
       "pixels": 500
     },
     "wait": 1.5
   }
   ```

### Comment Positioning Tips

Comment section elements are even more unstable, recommendations:

1. **Use core sentences from comment content** (not the beginning, to avoid duplication with other comments)
2. **Combine with author username**: `@username: comment content`
3. **Prioritize screenshot backups**: Popular tweet comment ordering changes

---

## Selector Stability Analysis

### Twitter DOM Structure Characteristics

| Element | Selector | Stability | Notes |
|---------|----------|-----------|-------|
| Tweet Container | `article[data-testid="tweet"]` | ✅ Stable | Official test ID |
| User Avatar | `[data-testid="Tweet-User-Avatar"]` | ✅ Stable | |
| Tweet Text | `[data-testid="tweetText"]` | ✅ Stable | |
| Reply Button | `[data-testid="reply"]` | ✅ Stable | |
| Retweet Button | `[data-testid="retweet"]` | ✅ Stable | |
| Like Button | `[data-testid="like"]` | ✅ Stable | |
| Share Button | `[data-testid="share"]` | ⚠️ Medium | |
| CSS Class Names | `.css-*`, `.r-*` | ❌ Unstable | Generated by CSS-in-JS |

### Recommended Highlight Selectors

```json
{
  "action": "highlight",
  "selector": "article[data-testid='tweet']:has([data-testid='tweetText']:contains('target text'))",
  "duration": 2
}
```

**Note**: `:contains()` is a non-standard selector that requires JavaScript implementation. In practice, recommend using `scroll_to` + `highlight` combination.

---

## Visual Effect Combinations

### Recommended Sequence for Displaying Tweets

```json
{
  "actions": [
    {"action": "scroll_to", "text": "target tweet text feature", "wait": 0.5},
    {"action": "highlight", "selector": "article:has(:scope *:contains('target text'))", "duration": 2},
    {"action": "wait", "seconds": 0.5}
  ]
}
```

### Recommended Sequence for Displaying Comments

```json
{
  "actions": [
    {"action": "scroll_to", "text": "comment text feature", "wait": 0.5},
    {"action": "pointer", "selector": "[data-testid='tweetText']", "duration": 1.5},
    {"action": "wait", "seconds": 0.5}
  ]
}
```

---

## Common Issues and Solutions

### Q1: Tweet/Comment Loads Slowly

**Cause**: Network latency, Twitter rate limiting

**Solution**:
```json
{
  "action": "navigate",
  "url": "https://x.com/user/status/123",
  "wait": 5  // Increase wait time
}
```

### Q2: scroll_to Cannot Find Element

**Possible Causes**:
1. Text is truncated with ellipsis (`...`)
2. Text contains special characters
3. Page hasn't fully loaded yet

**Solution**:
```bash
# Wait for page to stabilize first
uv run frago wait 2

# Use shorter core text fragment
uv run frago scroll-to "core keywords"
```

### Q3: Comment Position Varies at Different Times

**Cause**: Popular tweet comments are sorted by popularity, which changes dynamically

**Solution**:
1. Take screenshots immediately when collecting material
2. Use screenshots as backup footage during recording
3. Or accept the flexibility of "showing different comments"

### Q4: Highlight Effect Covers Wrong Element

**Cause**: Selector not precise enough

**Solution**:
```json
{
  "action": "highlight",
  "selector": "article[data-testid='tweet']:nth-of-type(3)",  // Specify which one
  "duration": 2
}
```

Or use `scroll_to` to position first, then highlight elements in the current viewport center.

---

## References

- Twitter DOM structure change tracking: Observe changes in `data-testid` attributes
- frago scroll-to command: `uv run frago scroll-to --help`
- Video production recipe: `examples/workflows/video_produce_from_script/recipe.md`

---

**Last Updated**: 2025-11-28
