Files
msh-system/docs/Testing/iframe-testing-workaround.md

379 lines
10 KiB
Markdown
Raw Permalink Normal View History

# Working Around Iframe Testing Limitations
## Problem Statement
The H5 application uses an iframe-based wrapper (`/static/html/pc.html`) which prevents automated browser testing tools from interacting with the actual application content. The iframe loads the mobile app at `/` inside it, creating an isolated browsing context.
## Architecture Diagram
```
┌─────────────────────────────────────────┐
│ http://localhost:8080/static/html/pc.html │
│ ┌─────────────────────────────────────┐ │
│ │ <iframe src="/"> │ │
│ │ ┌───────────────────────────────┐ │ │
│ │ │ Actual H5 App │ │ │
│ │ │ (慢生活营养专家) │ │ │
│ │ │ │ │ │
│ │ │ - User Card │ │ │
│ │ │ - Function Cards │ │ │
│ │ │ - Navigation │ │ │
│ │ └───────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
Browser Tools CAN access: PC wrapper (outer page)
Browser Tools CANNOT access: Iframe content (actual app)
```
## Why This Happens
From `/msh_single_uniapp/static/html/pc.html`:
```html
<iframe src="/" id="iframe"></iframe>
```
The pc.html wrapper:
1. Detects screen width
2. If width > 450px: Shows centered iframe with border (PC view)
3. If width ≤ 420px: Redirects to `/` (but still loads through router)
4. Sets `window.isPC = true` flag
## Current Limitations
### What Works ✅
- Page navigation (can change URL)
- Screenshot capture (visual verification)
- Network monitoring (API calls visible)
- Console log reading (errors visible)
- Page load timing
### What Doesn't Work ❌
- Element clicking (no refs inside iframe)
- Form input (no access to input fields)
- Text selection (isolated context)
- Element attribute reading (no refs)
- Hover interactions
## Solutions & Workarounds
### Solution 1: Manual Testing (Current Approach)
**Status:** ✅ Implemented
Use the comprehensive manual testing checklist:
- `/docs/Testing/manual-testing-checklist.md`
**Pros:**
- Works immediately
- No code changes required
- Can test all features
- Human verification of UX
**Cons:**
- Time-consuming
- Not reproducible
- Human error possible
- Cannot automate regression tests
---
### Solution 2: Direct H5 Access (Dev Environment)
**Status:** 🔶 Recommended for Testing
**Step A: Modify pc.html for Testing**
Create a test version that bypasses iframe:
```javascript
// Add to pc.html temporarily
if (window.location.search.includes('direct=true')) {
window.location.href = '/';
}
```
Then access: `http://localhost:8080/static/html/pc.html?direct=true`
**Step B: Access Root Directly with Mobile User-Agent**
The app routing logic checks for mobile devices. Browser tools can spoof user-agent:
```javascript
// In browser console before navigation:
Object.defineProperty(navigator, 'userAgent', {
get: function () {
return 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)';
}
});
```
Then navigate to `http://localhost:8080/`
**Step C: Modify Vue Router for Test Mode**
Add a query parameter to bypass PC detection:
In your router configuration or App.vue:
```javascript
// If ?test=true in URL, don't redirect to pc.html
if (this.$route.query.test === 'true') {
// Stay on current page
}
```
Access: `http://localhost:8080/?test=true`
---
### Solution 3: E2E Framework with Iframe Support
**Status:** 📋 Future Implementation
#### Option A: Playwright
```javascript
// Playwright can switch to iframe context
const page = await browser.newPage();
await page.goto('http://localhost:8080');
// Switch to iframe
const iframe = page.frameLocator('#iframe');
await iframe.locator('.login-button').click();
```
#### Option B: Cypress with iframe plugin
```javascript
// Install: npm install -D cypress-iframe
cy.visit('http://localhost:8080');
cy.frameLoaded('#iframe');
cy.iframe().find('.login-button').click();
```
#### Option C: Puppeteer
```javascript
const page = await browser.newPage();
await page.goto('http://localhost:8080');
// Get iframe
const frameHandle = await page.$('#iframe');
const frame = await frameHandle.contentFrame();
await frame.click('.login-button');
```
---
### Solution 4: Remove Iframe Wrapper (Architecture Change)
**Status:** 🎯 Long-term Recommendation
**Current Architecture:**
```
User → localhost:8080 → pc.html (checks screen size) → iframe src="/"
Actual H5 App
```
**Proposed Architecture:**
```
User → localhost:8080 → Direct H5 App
(CSS media queries handle responsive design)
```
**Benefits:**
- ✅ Enables automated testing
- ✅ Better performance (no iframe overhead)
- ✅ Simpler architecture
- ✅ Better SEO
- ✅ Easier debugging
**Changes Required:**
1. **Remove pc.html wrapper**
2. **Use CSS media queries for responsive design:**
```css
/* Instead of iframe with fixed size */
@media screen and (min-width: 450px) {
.mobile-app {
max-width: 375px;
margin: 0 auto;
border: 1px solid #f5f5f5;
border-radius: 4px;
}
}
```
3. **Update build configuration:**
```javascript
// In vue.config.js or similar
publicPath: '/',
// Remove redirect logic
```
**Implementation Estimate:** 2-4 hours
---
## Recommended Testing Strategy
### Phase 1: Current (Manual Testing)
- Use manual testing checklist
- Document all findings
- Capture screenshots
- ~2-3 hours of testing
### Phase 2: Quick Win (Direct Access)
- Implement Solution 2 (query parameter bypass)
- Enable automated testing for critical paths
- ~1 hour implementation
- Saves ~10 hours/week in testing
### Phase 3: Proper Tooling (E2E Framework)
- Set up Playwright or Cypress with iframe support
- Create automated test suite
- ~1 week implementation
- Full regression coverage
### Phase 4: Architecture Improvement (Remove Iframe)
- Refactor to remove iframe wrapper
- Use responsive CSS instead
- ~1 day implementation
- Permanent fix, enables all testing tools
---
## Temporary Testing Script
For immediate testing needs, create this script:
**File:** `test-helpers/direct-access.js`
```javascript
// Run this in browser console to enable direct testing
(function() {
// Method 1: Remove iframe and show content directly
const iframe = document.getElementById('iframe');
if (iframe) {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
document.body.innerHTML = iframeDoc.body.innerHTML;
// Copy styles
const iframeStyles = iframeDoc.getElementsByTagName('style');
for (let style of iframeStyles) {
document.head.appendChild(style.cloneNode(true));
}
console.log('✅ Iframe content extracted. You can now test directly.');
}
// Method 2: Add test hooks
window.testMode = true;
window.getIframeDoc = () => {
return iframe.contentDocument || iframe.contentWindow.document;
};
console.log('✅ Test helpers loaded. Use window.getIframeDoc() to access iframe.');
})();
```
**Usage:**
1. Open browser DevTools
2. Paste script in console
3. Press Enter
4. Content now accessible for testing
---
## Testing Without Iframe Access
### Approach 1: API Testing
Since network requests are visible, test APIs directly:
```javascript
// Test login API
fetch('http://127.0.0.1:20822/api/front/login/mobile', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone: '18621813282',
password: 'A123456'
})
})
.then(r => r.json())
.then(console.log);
```
### Approach 2: Visual Testing
Use screenshot comparison tools:
1. Take screenshot of expected state
2. Take screenshot after changes
3. Compare images using tools like:
- pixelmatch
- looks-same
- BackstopJS
### Approach 3: Network Monitoring
Verify functionality by monitoring network calls:
1. User clicks button
2. Check if correct API called
3. Verify response
4. Check if UI updates (via screenshot)
---
## Implementation Priority
### High Priority (This Week)
1. ✅ Complete manual testing
2. ⏳ Fix known configuration issue
3. ⏳ Document manual test results
### Medium Priority (This Month)
1. 📋 Implement Solution 2 (direct access for testing)
2. 📋 Set up API testing suite
3. 📋 Visual regression testing setup
### Low Priority (This Quarter)
1. 📋 Evaluate E2E framework (Playwright vs Cypress)
2. 📋 Consider architecture refactoring
3. 📋 Implement automated test suite
---
## Questions & Answers
**Q: Why does the app use an iframe?**
A: To provide a centered mobile view on desktop browsers while maintaining the mobile H5 codebase. It's a common pattern for mobile-first apps.
**Q: Can I just disable the iframe?**
A: Yes, but it requires code changes. See Solution 4 above.
**Q: Will removing the iframe break anything?**
A: No, if done properly. The iframe is just a container. The app logic is independent.
**Q: What's the fastest way to enable automated testing?**
A: Implement Solution 2 (query parameter to bypass iframe). Takes ~1 hour, enables all browser testing tools.
**Q: Should we always use iframes?**
A: No. Modern responsive design with CSS media queries is preferred. Iframes add complexity and testing difficulty.
---
## Resources
### Documentation
- [MDN: Working with iframes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
- [Playwright: Frames](https://playwright.dev/docs/frames)
- [Cypress: Iframes](https://docs.cypress.io/api/commands/its#Iframe-Support)
### Tools
- [cypress-iframe plugin](https://github.com/kgroat/cypress-iframe)
- [Playwright](https://playwright.dev/)
- [Puppeteer](https://pptr.dev/)
### Testing Strategies
- [Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
- [Visual Regression Testing](https://percy.io/visual-testing)
---
**Last Updated:** March 2, 2026
**Status:** Documented
**Recommended Action:** Implement Solution 2 for immediate testing needs