Add C4A-Script support and documentation

- Generate OneShot js code geenrator
- Introduced a new C4A-Script tutorial example for login flow using Blockly.
- Updated index.html to include Blockly theme and event editor modal for script editing.
- Created a test HTML file for testing Blockly integration.
- Added comprehensive C4A-Script API reference documentation covering commands, syntax, and examples.
- Developed core documentation for C4A-Script, detailing its features, commands, and real-world examples.
- Updated mkdocs.yml to include new C4A-Script documentation in navigation.
This commit is contained in:
UncleCode
2025-06-07 23:07:19 +08:00
parent ca03acbc82
commit 08a2cdae53
46 changed files with 6914 additions and 326 deletions

View File

@@ -0,0 +1,7 @@
GO https://store.example.com/product/laptop
WAIT `.product-details` 8
CLICK `button.add-to-cart`
WAIT `.cart-notification` 3
CLICK `.cart-icon`
WAIT `.checkout-btn` 5
CLICK `.checkout-btn`

View File

@@ -0,0 +1,43 @@
# Advanced control flow with IF, EXISTS, and REPEAT
# Define reusable procedures
PROC handle_cookie_banner
IF (EXISTS `.cookie-banner`) THEN CLICK `.accept-cookies`
IF (EXISTS `.privacy-notice`) THEN CLICK `.dismiss-privacy`
ENDPROC
PROC scroll_to_load
SCROLL DOWN 500
WAIT 0.5
ENDPROC
PROC try_login
CLICK `#email`
TYPE "user@example.com"
CLICK `#password`
TYPE "secure123"
CLICK `button[type="submit"]`
WAIT 2
ENDPROC
# Main script
GO https://example.com
WAIT 2
# Handle popups
handle_cookie_banner
# Conditional navigation based on login state
IF (EXISTS `.user-menu`) THEN CLICK `.dashboard-link` ELSE try_login
# Repeat scrolling based on content count
REPEAT (scroll_to_load, 5)
# Load more content while button exists
REPEAT (CLICK `.load-more`, `document.querySelector('.load-more') && !document.querySelector('.no-more-content')`)
# Process items conditionally
IF (`document.querySelectorAll('.item').length > 10`) THEN EVAL `console.log('Found ' + document.querySelectorAll('.item').length + ' items')`
# Complex condition with viewport check
IF (`window.innerWidth < 768 && document.querySelector('.mobile-menu')`) THEN CLICK `.mobile-menu-toggle`

View File

@@ -0,0 +1,8 @@
GO https://myapp.com
WAIT 2
IF (EXISTS `.user-avatar`) THEN CLICK `.logout` ELSE CLICK `.login`
WAIT `#auth-form` 5
IF (EXISTS `#auth-form`) THEN TYPE "user@example.com"
IF (EXISTS `#auth-form`) THEN PRESS Tab
IF (EXISTS `#auth-form`) THEN TYPE "password123"
IF (EXISTS `#auth-form`) THEN CLICK `button[type="submit"]`

View File

@@ -0,0 +1,56 @@
# Data extraction example
# Scrapes product information from an e-commerce site
# Navigate to products page
GO https://shop.example.com/products
WAIT `.product-list` 10
# Scroll to load lazy-loaded content
SCROLL DOWN 500
WAIT 1
SCROLL DOWN 500
WAIT 1
SCROLL DOWN 500
WAIT 2
# Extract product data
EVAL `
// Extract all product information
const products = Array.from(document.querySelectorAll('.product-card')).map((card, index) => {
return {
id: index + 1,
name: card.querySelector('.product-title')?.textContent?.trim() || 'N/A',
price: card.querySelector('.price')?.textContent?.trim() || 'N/A',
rating: card.querySelector('.rating')?.textContent?.trim() || 'N/A',
availability: card.querySelector('.in-stock') ? 'In Stock' : 'Out of Stock',
image: card.querySelector('img')?.src || 'N/A'
};
});
// Log results
console.log('=== Product Extraction Results ===');
console.log('Total products found:', products.length);
console.log(JSON.stringify(products, null, 2));
// Save to localStorage for retrieval
localStorage.setItem('scraped_products', JSON.stringify(products));
`
# Optional: Click on first product for details
CLICK `.product-card:first-child`
WAIT `.product-details` 5
# Extract detailed information
EVAL `
const details = {
description: document.querySelector('.product-description')?.textContent?.trim(),
specifications: Array.from(document.querySelectorAll('.spec-item')).map(spec => ({
label: spec.querySelector('.spec-label')?.textContent,
value: spec.querySelector('.spec-value')?.textContent
})),
reviews: document.querySelector('.review-count')?.textContent
};
console.log('=== Product Details ===');
console.log(JSON.stringify(details, null, 2));
`

View File

@@ -0,0 +1,8 @@
GO https://company.com/contact
WAIT `form#contact` 10
TYPE "John Smith"
PRESS Tab
TYPE "john@email.com"
PRESS Tab
TYPE "Need help with my order"
CLICK `button[type="submit"]`

View File

@@ -0,0 +1,7 @@
GO https://news.example.com
WAIT `.article-list` 5
REPEAT (SCROLL DOWN 500, 3)
WAIT 1
REPEAT (CLICK `.load-more`, `document.querySelector('.load-more') !== null`)
WAIT 2
IF (`document.querySelectorAll('.article').length > 20`) THEN EVAL `console.log('Loaded enough articles')`

View File

@@ -0,0 +1,36 @@
# Login flow with error handling
# Demonstrates procedures, variables, and conditional checks
# Define login procedure
PROC perform_login
CLICK `input#email`
TYPE $email
CLICK `input#password`
TYPE $password
CLICK `button.login-submit`
ENDPROC
# Set credentials
SET email = "user@example.com"
SET password = "securePassword123"
# Navigate to login page
GO https://app.example.com/login
WAIT `.login-container` 15
# Attempt login
perform_login
# Wait for page to load
WAIT 3
# Check if login was successful
EVAL `
if (document.querySelector('.dashboard')) {
console.log('Login successful - on dashboard');
} else if (document.querySelector('.error-message')) {
console.log('Login failed:', document.querySelector('.error-message').textContent);
} else {
console.log('Unknown state after login');
}
`

View File

@@ -0,0 +1,106 @@
# Multi-step e-commerce workflow
# Complete purchase flow with procedures and error handling
# Reusable procedures
PROC search_product
CLICK `input.search-bar`
TYPE $search_term
PRESS Enter
WAIT `.search-results` 10
ENDPROC
PROC add_first_item_to_cart
CLICK `.product-item:first-child .add-to-cart`
WAIT ".added-to-cart-notification" 3
ENDPROC
PROC go_to_checkout
CLICK `.cart-icon`
WAIT `.cart-drawer` 5
CLICK `button.proceed-to-checkout`
WAIT `.checkout-page` 10
ENDPROC
PROC fill_customer_info
# Billing information
CLICK `#billing-firstname`
TYPE $first_name
CLICK `#billing-lastname`
TYPE $last_name
CLICK `#billing-email`
TYPE $email
CLICK `#billing-phone`
TYPE $phone
# Address
CLICK `#billing-address`
TYPE $address
CLICK `#billing-city`
TYPE $city
CLICK `#billing-state`
TYPE $state
CLICK `#billing-zip`
TYPE $zip
ENDPROC
PROC select_shipping
CLICK `input[value="standard"]`
WAIT 1
ENDPROC
# Set all required variables
SET search_term = "wireless headphones"
SET first_name = "John"
SET last_name = "Doe"
SET email = "john.doe@example.com"
SET phone = "555-0123"
SET address = "123 Main Street"
SET city = "San Francisco"
SET state = "CA"
SET zip = "94105"
# Main workflow starts here
GO https://shop.example.com
WAIT `.homepage-loaded` 10
# Step 1: Search and add to cart
search_product
EVAL `console.log('Found', document.querySelectorAll('.product-item').length, 'products')`
add_first_item_to_cart
# Add a second item
CLICK `.product-item:nth-child(2) .add-to-cart`
WAIT 2
# Step 2: Go to checkout
go_to_checkout
# Step 3: Fill customer information
fill_customer_info
# Step 4: Select shipping method
select_shipping
# Step 5: Continue to payment
CLICK `button.continue-to-payment`
WAIT `.payment-section` 10
# Log order summary
EVAL `
const orderTotal = document.querySelector('.order-total')?.textContent;
const itemCount = document.querySelectorAll('.order-item').length;
console.log('=== Order Summary ===');
console.log('Items:', itemCount);
console.log('Total:', orderTotal);
// Get all items
const items = Array.from(document.querySelectorAll('.order-item')).map(item => ({
name: item.querySelector('.item-name')?.textContent,
quantity: item.querySelector('.item-quantity')?.textContent,
price: item.querySelector('.item-price')?.textContent
}));
console.log('Items:', JSON.stringify(items, null, 2));
`
# Note: Stopping here before actual payment submission
EVAL `console.log('Workflow completed - stopped before payment submission')`

View File

@@ -0,0 +1,8 @@
GO https://app.example.com
WAIT `.nav-menu` 8
CLICK `a[href="/products"]`
WAIT 2
CLICK `a[href="/about"]`
WAIT 2
BACK
WAIT 1

View File

@@ -0,0 +1,8 @@
GO https://myapp.com/login
WAIT `input#email` 5
CLICK `input#email`
TYPE "user@example.com"
PRESS Tab
TYPE "password123"
CLICK `button.login-btn`
WAIT `.dashboard` 10

View File

@@ -0,0 +1,7 @@
GO https://responsive.site.com
WAIT 2
IF (`window.innerWidth < 768`) THEN CLICK `.mobile-menu`
IF (`window.innerWidth < 768`) THEN WAIT `.mobile-nav` 3
IF (`window.innerWidth >= 768`) THEN CLICK `.desktop-menu li:nth-child(2)`
REPEAT (CLICK `.next-slide`, 5)
IF (EXISTS `.cookie-banner`) THEN CLICK `.accept-cookies`

View File

@@ -0,0 +1,8 @@
GO https://news.site.com
WAIT `.article-list` 10
SCROLL DOWN 500
WAIT 1
SCROLL DOWN 500
WAIT 1
CLICK `.article:nth-child(5)`
WAIT `.article-content` 5

View File

@@ -0,0 +1,7 @@
GO https://shop.example.com
WAIT `.search-bar` 10
CLICK `.search-bar`
TYPE "wireless headphones"
PRESS Enter
WAIT `.results` 5
CLICK `.product-card:first-child`

View File

@@ -0,0 +1,19 @@
# Simple form submission example
# This script fills out a contact form and submits it
GO https://example.com/contact
WAIT `form#contact-form` 10
# Fill out the form fields
CLICK `input[name="name"]`
TYPE "Alice Smith"
PRESS Tab
TYPE "alice@example.com"
PRESS Tab
TYPE "I'd like to learn more about your services"
# Submit the form
CLICK `button[type="submit"]`
# Wait for success message
WAIT "Thank you for your message" 5

View File

@@ -0,0 +1,11 @@
PROC fill_field
TYPE "test@example.com"
PRESS Tab
ENDPROC
GO https://forms.example.com
WAIT `form` 5
IF (EXISTS `input[type="email"]`) THEN CLICK `input[type="email"]`
IF (EXISTS `input[type="email"]`) THEN fill_field
REPEAT (PRESS Tab, `document.activeElement.type !== 'submit'`)
CLICK `button[type="submit"]`