การตรวจสอบและการรอองค์ประกอบ
ใช้ assertVisible, assertNotVisible และ waitForAnimationToEnd ใน Maestro YAML เพื่อตรวจสอบสถานะ UI และจัดการตัวหมุนโหลดก่อนดำเนินโฟลว์ต่อ
การตรวจสอบและการรอองค์ประกอบ เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
Assertions Are the Heart of Tests
A Maestro flow without assertions only tells you the app did not crash. Assertions verify that the app shows the correct content after each action. They are the part of the test that actually checks correctness.
Maestro provides a rich set of assertion commands: checking that elements are visible, not visible, contain specific text, or are enabled/disabled. Learning to write precise, targeted assertions is what distinguishes a useful E2E test from one that only provides false confidence.
assertVisible and assertNotVisible
assertVisible checks that an element with the given text or id is currently displayed on screen. It retries for up to 5 seconds by default, making it resilient to brief loading delays.
assertNotVisible is the opposite — it verifies that an element is NOT on screen. Use this to confirm that an error message disappears after the user fixes their input, or that a loading spinner is gone after data loads.
# Verify the welcome message is visible
- assertVisible:
text: 'Welcome, Alice!'
# Verify with testID
- assertVisible:
id: 'home-screen-header'
# Verify loading spinner is gone
- assertNotVisible:
id: 'loading-spinner'
# Verify error banner is not shown initially
- assertNotVisible:
text: 'Something went wrong'Configuring Assertion Timeouts
The default assertion timeout in Maestro is 5 seconds. If your app makes a network call before showing content, 5 seconds may not be enough on a slow CI machine or with a real network. Override the timeout per assertion with the timeout option (in milliseconds).
A good practice is to set longer timeouts on the first assertion after a network call and shorter ones for assertions on content that should appear immediately after a tap (like a navigation transition).
# Short timeout for immediate UI changes
- tapOn:
text: 'Profile'
- assertVisible:
text: 'Edit Profile'
timeout: 2000 # 2 seconds — should appear immediately
# Long timeout for network-dependent content
- tapOn:
text: 'Load Feed'
- assertVisible:
text: 'Latest Posts'
timeout: 10000 # 10 seconds — allows for API callwaitForAnimationToEnd
Animations can cause assertion failures even when the content is technically visible. If an element is animating in (fading, sliding, scaling), Maestro might tap or assert on it before the animation completes, leading to flaky tests.
Add waitForAnimationToEnd after a tap that triggers a screen transition or an animated list update. Maestro pauses until the UI is fully still before continuing. This eliminates the most common source of flakiness in mobile E2E tests.
# Screen transition — wait for animation
- tapOn:
text: 'View Details'
- waitForAnimationToEnd
- assertVisible:
text: 'Post Details'
# Modal appearance — wait for slide-up animation
- tapOn:
text: 'Show Options'
- waitForAnimationToEnd
- assertVisible:
id: 'options-modal'
# Pull-to-refresh — wait for the refresh animation
- scroll:
direction: UP
speed: SLOW
- waitForAnimationToEndScroll Then Assert
Content below the fold is not visible to Maestro assertions even if it is rendered. Use the scroll command to bring off-screen content into view before asserting on it.
The scroll command supports directions (UP, DOWN, LEFT, RIGHT) and a speed option. You can also scroll within a specific container by adding an element filter, which is useful for scrollable content inside a modal or a tab panel.
# Scroll down to find a button below the fold
- scroll:
direction: DOWN
- assertVisible:
text: 'Load More'
# Scroll with slow speed for smoother interaction
- scroll:
direction: DOWN
speed: SLOW
# Scroll within a specific container
- scroll:
direction: DOWN
element:
id: 'settings-list'
- assertVisible:
text: 'Privacy Policy'assertVisible with Partial Text
Sometimes you want to assert on content that contains a dynamic value — like a username, count, or timestamp — that you cannot hard-code. Maestro supports regex patterns in text assertions to match partial or dynamic content.
Add regexp: true and use a regular expression in the text field. For example, match any string that starts with 'Hello,' followed by any name, or match a timestamp pattern like \d{2}:\d{2}.
# Assert text starts with 'Hello,' regardless of the username
- assertVisible:
text: 'Hello,.*'
regexp: true
# Assert a price is displayed (format: $X.XX)
- assertVisible:
text: '\$[0-9]+\.[0-9]{2}'
regexp: true
# Assert any timestamp in HH:MM format
- assertVisible:
text: '[0-9]{2}:[0-9]{2}'
regexp: trueConditional Flows with runFlow and Optional
Mobile apps sometimes show optional dialogs (permission requests, update prompts, onboarding) that may or may not appear depending on device state. Use optional: true on tapOn to dismiss these dialogs only if they appear.
Combine optional taps with conditional flows using Maestro's JavaScript-based condition syntax. If a particular element is visible, take one path; otherwise take another. This makes your flows resilient to non-deterministic UI states.
# Dismiss optional permission dialog if it appears
- tapOn:
text: 'Allow'
optional: true
# Dismiss optional update dialog
- tapOn:
text: 'Not Now'
optional: true
# Now continue with the main flow
- assertVisible:
text: 'Home'
# Conditional: skip tutorial if already seen
- runFlow:
when:
visible:
text: 'Skip Tutorial'
file: subflows/skip-tutorial.yamlassertVisible vs assertCondition
assertVisible checks for an element in the current view. For more complex conditions — like verifying an element's count or checking that the screen title matches a pattern — use assertCondition with a JavaScript expression.
The JavaScript expression has access to the current screen's elements. Return true from the expression if the condition passes. This gives you the full power of JavaScript for complex assertions that go beyond simple element visibility.
# Simple visibility check
- assertVisible:
text: 'Settings'
# JavaScript condition assertion
- assertCondition:
condition: |-
const elements = maestro.getViewHierarchy();
const count = elements.filter(e => e.text === 'Item').length;
count === 5
# Alternative: check that a number is in a range
- evalScript: |
const badge = maestro.viewHierarchy.find(e => e.id === 'badge-count');
if (!badge || parseInt(badge.text) < 1) throw new Error('Badge should show count > 0');Taking Screenshots in Flows
Maestro can take screenshots at any point in a flow with the takeScreenshot command. These screenshots are saved to disk and included in the test report. Use them to capture UI state at critical checkpoints for visual documentation or debugging.
Provide an absolute path for the screenshot file. Maestro also automatically takes a screenshot when an assertion fails, so you get a visual of exactly what was on screen when the test broke.
# Take a screenshot after login to document the home screen
- launchApp:
clearState: true
- tapOn:
id: 'email-input'
- inputText: 'user@example.com'
- tapOn:
id: 'password-input'
- inputText: 'password123'
- tapOn:
text: 'Sign In'
- waitForAnimationToEnd
- assertVisible:
text: 'Home'
- takeScreenshot: /tmp/maestro-screenshots/home-screenSwipe Gestures
Use the swipe command to simulate swipe gestures. You can swipe from a percentage-based start point to an end point, which is useful for dismissing modals, navigating carousels, or triggering swipe-to-delete on list items.
Specify start and end points as percentages of the screen dimensions. For example, to swipe left on a card to reveal a delete button: start at 80% from the left, end at 20% from the left, at 50% height.
# Swipe left to delete a list item
- swipe:
startX: 80%
startY: 50%
endX: 20%
endY: 50%
duration: 300
# Swipe down to dismiss a modal
- swipe:
startX: 50%
startY: 30%
endX: 50%
endY: 90%
# Swipe right for next card in a carousel
- swipe:
startX: 80%
startY: 50%
endX: 20%
endY: 50%
- waitForAnimationToEnd
- assertVisible:
text: 'Card 2 of 5'Writing Resilient Assertions
The best assertions test the user-visible outcome, not implementation details. Instead of asserting that a specific component ID is present, assert on the text the user would see. Instead of asserting on a loading state, assert on the final content that appears after loading.
Keep assertions specific enough to catch real bugs but flexible enough to survive minor UI changes. An assertion that checks the exact spacing or color of a button is fragile — an assertion that checks the button's label and that it is tappable is much more durable.
# Too fragile: implementation-specific
- assertVisible:
id: 'PrimaryButton-f3a2'
# Better: user-visible text
- assertVisible:
text: 'Submit Order'
# Too fragile: exact error code
- assertVisible:
text: 'Error: AUTH_001'
# Better: user-friendly message
- assertVisible:
text: 'Invalid email or password'Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: how to use assertVisible, assertNotVisible, and timeout to write precise Maestro assertions, how waitForAnimationToEnd prevents flaky tests caused by UI animations, and how to use optional: true for non-deterministic dialogs and swipe commands for gesture-driven UI. Next up we write multi-screen user journey flows that test complete app features end to end.
เรียนรู้ JavaScript ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การตรวจสอบและการรอองค์ประกอบ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตรวจสอบและการรอองค์ประกอบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การตรวจสอบและการรอองค์ประกอบ”
ใช้ assertVisible, assertNotVisible และ waitForAnimationToEnd ใน Maestro YAML เพื่อตรวจสอบสถานะ UI และจัดการตัวหมุนโหลดก่อนดำเนินโฟลว์ต่อ คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การตรวจสอบและการรอองค์ประกอบ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม
ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การติดตั้ง Maestro และรันโฟลว์แรก
- การตรวจสอบและการรอองค์ประกอบ
- การทดสอบเส้นทางการใช้งานหลายหน้าจอ
- Maestro ใน CI ด้วย GitHub Actions