In this post
  1. TikTok: the time picker that jumps by three
  2. X: the toolbar that changes height
  3. Meta: the click that opens a system dialog
  4. The pattern
  5. The three rules that survived
  6. 1. Never reuse a coordinate across calls
  7. 2. Verify in a call separate from the action
  8. 3. Wait for conditions, never for time
  9. What this has to do with building apps
  10. The honest scoreboard

After fixing the two YouTube bugs — covered in part 1 — we expected the rest to be routine. TikTok, X, Instagram, Facebook, Kwai and Reddit were left.

Every platform produced a new failure. And every new failure, looked at closely, was the same failure.

TikTok: the time picker that jumps by three

TikTok's scheduler does not accept a typed time. It is a scroll picker with behaviour nobody documents:

  • clicking the last visible row of the hour column advances +3 hours
  • the value actually selected is the middle row, not the row you clicked
  • the dropdown's position on screen varies with available space

So you click "18" and select "15". Or "21". Depending on where the dropdown decided to open.

Video 15 got scheduled for 18:10 instead of 18:00. The exact reason: the verification had been issued in the same call as the click. The response described the state before the click took effect, and we read that response as confirmation.

Verifying and acting in one call is the same mistake as reading a value and using it after another thread wrote to it. Here the other thread is the UI.

X: the toolbar that changes height

On X the schedule button lives in the composer toolbar, which changes height in three situations:

Composer stateButton position
One line of texty = 312
Two lines of texty = 337
Link preview card loadedy = 625

Three different values, and the third only appears seconds later, once X finishes fetching the preview. A coordinate captured before the card loads points at the wrong place by the time the click happens.

And that is not all: the window resizes on its own between actions. Nothing that depends on absolute position survives that.

Meta: the click that opens a system dialog

The most interesting case was Meta's video editor. The visible upload button opens the operating system's native file dialog — outside the browser, and therefore out of reach of any page automation.

The fix was not clicking better. It was understanding what the button does: it calls click() on a <input type="file"> the application creates on the fly. With that element located, the file goes straight to it — no system dialog involved.

When a click opens a system window, page automation ends there. The answer is not to keep clicking: it is to find the element the click triggers.

The pattern

PlatformWhat movesWhat breaks
YouTubeTitle field grows as you typeThe description click lands in the title
TikTokDropdown opens up or downSilently selects the wrong hour
XToolbar shifts when the preview loadsThe schedule click misses
MetaUpload element is created on clickThe system dialog blocks everything
InstagramGrid changes after upload"Next" moves
RedditEditor toggles markdown / rich textText lands in the wrong field

Six interfaces, six different reasons, one problem: between the moment you read the screen and the moment you click, the screen changed.

The three rules that survived

1. Never reuse a coordinate across calls

A coordinate has a shelf life measured in milliseconds. Either you locate the element and click it, or you read its position in the same action that clicks. Storing (694, 337) for the next step is storing a pointer to freed memory.

2. Verify in a call separate from the action

This is the rule that cost the most to learn and paid the most. Checking and clicking together produces a reading of the past. Confirm, then act.

3. Wait for conditions, never for time

wait 3 seconds is a guess. wait until the footer says "Checks complete" is a contract. Every time the process depended on a fixed delay, it failed on a larger video or a slower connection.

  • YouTube: wait for the footer text to change
  • TikTok: the first upload attempt always fails with an anti-automation

guard; reloading and retrying works. That is a condition, not a delay.

  • X: the schedule dialog is not in the accessibility tree for the first few

seconds even though it is visibly open; repeating the query resolves it

What this has to do with building apps

Everything, which is why this post sits in the engineering track.

The same three rules describe UI testing, and they explain why end-to-end tests have a reputation for flakiness. A test that waits on time, stores coordinates and asserts on state it does not control is flaky by construction — and the tooling takes the blame unfairly.

The short version, good for both:

Do not assert anything about a screen you did not just read. And do not read a screen in the same action that modifies it.

The honest scoreboard

YouTube — videos scheduled26%
TikTok — videos scheduled42%
Meta Reels — videos published29%

None of those is 100%, and the reasons are not technical: TikTok only allows scheduling 30 days ahead, and Meta enforces an upload rate limit that shows up as an upload stuck at 0% — no error, no warning, no network request. Waiting is the only fix.

That is engineering information too. Half the work of publishing at scale is not publishing: it is finding where each platform puts the brake and stopping hitting it.


In part 3: a post that looked published, appeared on our profile, and existed for nobody else.

Frequently asked questions

Why not always use element selectors instead of coordinates?

Because it is not always possible. Some components only respond to a real pointer event — clicking the element merely focuses it. In those cases the rule is to read the element's position at click time, never to reuse a coordinate captured earlier.

Which rule finally stabilised the process?

Separating verification from action. While we checked and clicked in the same call, the check described a state that no longer existed when the click landed. Verify, then act in the next call.

Does this apply to UI testing in general?

It does, and it is the same lesson as end-to-end testing: assert on state you control, wait for conditions rather than time, and never carry screen positions between steps. The difference here is that the UI belongs to someone else and changes without notice.