diff --git a/functional_tests/README.md b/functional_tests/README.md index 1c972b2..9e3557d 100644 --- a/functional_tests/README.md +++ b/functional_tests/README.md @@ -65,3 +65,20 @@ --- +**Execution Date:** 12/18/2025, 2:34:09 PM + +**Test Unique Identifier:** "roost_test_1766048227" + +**Input(s):** + 1. hebrew.docx + Path: /Users/iamdm/Desktop/atid/hebrew.docx + +**Test Output Folder:** + 1. [roost_test_1766048227.json](roost_test_1766048227/roost_test_1766048227.json) + 2. [roost_test_1766048227.feature](roost_test_1766048227/roost_test_1766048227.feature) + 3. [roost_test_1766048227.csv](roost_test_1766048227/roost_test_1766048227.csv) + 4. [roost_test_1766048227.xlsx](roost_test_1766048227/roost_test_1766048227.xlsx) + 5. [roost_test_1766048227.yaml](roost_test_1766048227/roost_test_1766048227.yaml) + +--- + diff --git a/functional_tests/roost_test_1766048227/.roost/roost_metadata.json b/functional_tests/roost_test_1766048227/.roost/roost_metadata.json new file mode 100644 index 0000000..c9ad38d --- /dev/null +++ b/functional_tests/roost_test_1766048227/.roost/roost_metadata.json @@ -0,0 +1,19 @@ +{ + "project": { + "name": "roost_test_1766048227", + "created_at": "2025-12-18T09:04:09.182Z", + "updated_at": "2025-12-18T09:04:09.182Z" + }, + "files": { + "input_files": [ + { + "fileName": "hebrew.docx", + "fileURI": "/var/tmp/Roost/RoostGPT/hapo-functional-test/1766048227/functional_tests/roost_test_1766048227/hebrew.docx", + "fileSha": "a3da2e9197" + } + ] + }, + "api_files": { + "input_files": [] + } +} \ No newline at end of file diff --git a/functional_tests/roost_test_1766048227/roost_test_1766048227.csv b/functional_tests/roost_test_1766048227/roost_test_1766048227.csv new file mode 100644 index 0000000..b571f0d --- /dev/null +++ b/functional_tests/roost_test_1766048227/roost_test_1766048227.csv @@ -0,0 +1,44 @@ +מסע רכישה מלא – מהבאנר הראשי ועד ולידציות בקופה (חסר מיקוד) +המשך התסריט – הזנת מיקוד וקבלת שגיאת אמצעי תשלום +מעבר לעמוד מס' 2 באמצעות לחיצה על הספרה 2 +כניסה למוצר באמצעות שם המוצר לעומת התמונה +הוספה לסל מדף הקטלוג (אם כפתור זמין) +עדכון כמויות וחישוב עלויות משלוח +קופון תקף לעומת קופון לא תקף +תהליך הזמנה מוצלח עם אמצעי תשלום זמין +שמירת סל לאחר רענון/ניווט חזרה/פתיחה מחדש +הסרת פריט מהסל +בדיקת Breadcrumbs וניווט חזרה לקטגוריה +הזנת פרטי חיוב בעברית ו-RTL +ולידציות שדות – אימייל/טלפון/מיקוד לא חוקיים +שינוי שפה לאנגלית וחזרה לעברית +נגישות – שימוש מלא במקלדת +התנהגות במצב חוסר מלאי +כשל רשת במהלך תשלום ושחזור +התנהגות לאחר לחיצה כפולה על PLACE ORDER +Responsive – ניווט, פאג'ינציה וכפתורים במובייל +בדיקת שינוי מיון קטלוג ושימור בחירה +בדיקת דירוג מוצר ותצוגת ביקורות +חישוב מע"מ ישראלי והצגת מטבע +בדיקת טופס – סימון חובה והבלטת שגיאות +פונקציית View Cart – ניווט נכון וקריאה לפעולה +בדיקת ריבוי שיטות משלוח ועדכון סכום ותיאור זמן אספקה +השוואת הוספה לסל מול הסרה – סכום כולל חוזר לברירת מחדל +ולידציות Checkout ב-API – חסר מיקוד לעומת אמצעי תשלום לא תקין +החלת קופון ב-API – הצלחה ושגיאה +עדכון שיטת משלוח ב-API והצלבת סכומים +יצירת הזמנה תקינה ב-API +התמדה של סל ב-API באמצעות סשן +ביצועים – זמני טעינה ותגובה בתהליך רכישה +סקיילביליות – עומס משתמשים בו-זמנית +אבטחה – TLS, HSTS, Cookie Flags ו-CSRF +פרטיות – מדיניות פרטיות והסכמות +אבטחת תשלומים – ציות ל-PCI DSS +אמינות – התמדה של סל לאחר timeout/ניתוק +נגישות – תאימות WCAG 2.1 AA +התאמה בין דפדפנים ומערכות הפעלה +ניטור ולוגים – תיעוד עסקאות ושגיאות +התאוששות מכשל שירות צד-שלישי (Gateway 5xx) +מניעת XSS/Injection בשדות הכתובת +מניעת דליפת פרטי לקוח ב-Referrer +יציבות RTL/LTR במעבר בין שפות \ No newline at end of file diff --git a/functional_tests/roost_test_1766048227/roost_test_1766048227.feature b/functional_tests/roost_test_1766048227/roost_test_1766048227.feature new file mode 100644 index 0000000..f068a0f --- /dev/null +++ b/functional_tests/roost_test_1766048227/roost_test_1766048227.feature @@ -0,0 +1,459 @@ +Feature: מסחר אלקטרוני - חוויית רכישה, ולידציות, קופונים, משלוח, אבטחה וביצועים + + Background: + Given כתובת האתר מוגדרת במשתנה סביבה 'WEB_BASE_URL' + And בסיס ה-API מוגדר במשתנה סביבה 'API_BASE_URL' + And סשן אורח התחלתי קיים עם זיהוי סשן + + # UI Tests + @ui @TC-F-001 + Scenario: מסע רכישה מלא – מהבאנר הראשי ועד ולידציות בקופה (חסר מיקוד) + Given אני נמצא בדף הבית בכתובת WEB_BASE_URL + When אני לוחץ על הכפתור "SHOP NOW" בבאנר "Latest Eyewear For You" + And אני גולל לתחתית עמוד הקטלוג ולוחץ על חץ "הבא" כדי לעבור לעמוד 2 + And אני בוחר את המוצר "Red Hoodie" באמצעות לחיצה על שם המוצר או התמונה + And בדף המוצר אני לוחץ "ADD TO CART" + And בהודעת ההוספה לסל אני לוחץ "VIEW CART" + And בסל אני בוחר לפי הסדר: "Local pickup" ואז "Delivery Express" ואז "Registered Mail" + And אני מאמת שהעלות הכוללת מתעדכנת: "Delivery Express" = "₪12.50", "Registered Mail" = "₪5.90", "Local pickup" = "₪0" + And אני לוחץ "PROCEED TO CHECKOUT" + And בעמוד הקופה אני ממלא: + | שדה | ערך | + | First name | Meital | + | Last name | Kenzi | + | Company | Menora | + | Country | Israel | + | Street address | Burla yehuda 1 | + | Apartment/Unit | 17 | + | Town/City | Tel Aviv, | + | Phone | 0544344345 | + | Email | meitalkenzi@gmail.com| + | Postcode/ZIP | | + And אני לוחץ "PLACE ORDER" + Then מוצגת הודעת שגיאה ברורה באזור ההודעות "Billing Postcode / ZIP is a required field." + And לא נוצרת הזמנה והמשתמש נשאר בדף הקופה עם ערכים שמורים + + @ui @TC-F-002 + Scenario: המשך התסריט – הזנת מיקוד וקבלת שגיאת אמצעי תשלום + Given אני נמצא בעמוד הקופה כאשר כל השדות מלאים למעט המיקוד + When אני מזין בשדה "Postcode/ZIP" את הערך "316547" + And אני לוחץ "PLACE ORDER" + Then מוצגת הודעת שגיאה "Invalid payment method" + And לא נוצרת הזמנה והמשתמש נשאר בדף הקופה עם הנתונים שמורים + + @ui @TC-F-003 + Scenario: מעבר לעמוד מס' 2 באמצעות לחיצה על הספרה 2 + Given עמוד קטלוג פתוח לאחר לחיצה על "SHOP NOW" + When אני לוחץ על הספרה "2" בפאג'ינציה + Then מוצגת אינדיקציה לעמוד 2 כגון "Showing 13–14 of 14 results" + And הספרה "2" מסומנת כפעילה + + @ui @TC-F-004 + Scenario Outline: כניסה למוצר באמצעות שם המוצר לעומת התמונה + Given עמוד 2 של הקטלוג פתוח + When אני לוחץ על <אלמנט_לחיצה> של "Red Hoodie" + Then נטען דף המוצר עם כותרת "Red Hoodie" + And מוצג נתיב פירורי לחם "Home / Men / Red Hoodie" + + Examples: + | אלמנט_לחיצה | + | שם המוצר | + | תמונת המוצר | + + @ui @TC-F-005 + Scenario: הוספה לסל מדף הקטלוג (אם כפתור זמין) + Given עמוד קטלוג שבו כפתור "Add to cart" זמין עבור "Red Hoodie" + When אני לוחץ "Add to cart" בכרטיס של "Red Hoodie" + Then מופיעה הודעת הצלחה/Toast שהמוצר נוסף + And בהודעה אני לוחץ "VIEW CART" ומגיע לעמוד הסל + And המוצר "Red Hoodie" מופיע בסל עם כמות 1, מחיר "₪150.00" ומטבע "₪" + + @ui @TC-F-006 + Scenario: עדכון כמויות וחישוב עלויות משלוח + Given סל פתוח עם "Red Hoodie" בכמות 1 + When אני משנה כמות ל-2 ולוחץ "Update cart" אם נדרש + And אני בוחר "Delivery Express" + Then הסכום הכולל מתעדכן ל-300 ₪ + "₪12.50" משלוח + When אני מחליף ל-"Registered Mail" + Then המשלוח מתעדכן ל-"₪5.90" והסכום הכולל מחושב בהתאם + When אני מחליף ל-"Local pickup" + Then המשלוח הוא "₪0" והסכום הכולל הוא 300 ₪ + + @ui @TC-F-007 @TC-F-008 + Scenario Outline: קופון תקף לעומת קופון לא תקף + Given סל פתוח עם לפחות פריט אחד + When אני פותח את אזור הקופון ולוחץ "Have a coupon? Click here to enter your code" + And אני מזין את הקוד "<קוד_קופון>" ולוחץ "Apply coupon" + Then <תוצאה_צפויה> + + Examples: + | קוד_קופון | תוצאה_צפויה | + | SALE10 | מוצגת שורת קופון עם סכום הנחה, סכום סופי מתעדכן במטבע "₪", ומופיעה הודעת הצלחה | + | ABC123 | מוצגת הודעת שגיאה ידידותית (בעברית אם האתר בעברית) וללא שינוי בסכום הכולל | + + @ui @TC-F-009 + Scenario Outline: תהליך הזמנה מוצלח עם אמצעי תשלום זמין + Given סל עם פריט אחד וכתובת בישראל + When אני לוחץ "PROCEED TO CHECKOUT" + And אני ממלא את כל פרטי החיוב כולל מיקוד תקין "6473421" + And אני בוחר שיטת משלוח "Local pickup" + And אני בוחר אמצעי תשלום "<אמצעי_תשלום>" + And אני מסמן הסכמה למדיניות אם נדרש + And אני לוחץ "PLACE ORDER" + Then מוצג עמוד אישור הזמנה עם מספר הזמנה + And מתקבל מייל אישור לכתובת שהוזנה + And אין הודעות שגיאה + + Examples: + | אמצעי_תשלום | + | Direct Bank Transfer | + | Cash on Delivery | + + @ui @TC-F-010 + Scenario: שמירת סל לאחר רענון/ניווט חזרה/פתיחה מחדש + Given סל עם פריט אחד לפחות + When אני מרענן את עמוד הסל + Then הפריטים נשמרים בסל + When אני נווט לעמוד הבית וחוזר לעמוד הסל + Then הפריטים נשמרים בסל + When אני סוגר את הדפדפן, פותח מחדש את האתר וחוזר לסל באותו התקן ודפדפן + Then הפריטים עדיין בסל + + @ui @TC-F-011 + Scenario: הסרת פריט מהסל + Given סל עם לפחות פריט אחד + When אני לוחץ על האייקון "X" ליד הפריט בסל + Then מופיעה הודעת "Cart updated" אם קיימת + And הפריט נמחק והסכום הכולל מתעדכן + And אם הסל ריק מוצג כפתור "Return to shop" + + @ui @TC-F-012 + Scenario: בדיקת Breadcrumbs וניווט חזרה לקטגוריה + Given דף המוצר "Red Hoodie" פתוח + When אני לוחץ על "Men" ב-Breadcrumbs + Then אני נוחת בעמוד קטגוריית Men הנכון + + @ui @TC-F-013 + Scenario: הזנת פרטי חיוב בעברית ו-RTL + Given שפת האתר היא עברית + When אני ממלא שם פרטי "דנה", שם משפחה "כהן", רחוב "יהודה הלוי 10", עיר "תל אביב", מיקוד "6473421", טלפון "0521234567", אימייל "dana@example.com" + And אני לוחץ "PLACE ORDER" (עם אמצעי תשלום תקף אם קיים) + Then אין בעיות כיווניות/יישור וכל השדות בעברית מוצגים נכון + And אם חסר מידע מוצגות הודעות בעברית והפוקוס מוצב על השדה הבעייתי + + @ui @TC-F-014 + Scenario Outline: ולידציות שדות – אימייל/טלפון/מיקוד לא חוקיים + Given עמוד קופה פתוח + When אני מזין אימייל "<אימייל>", טלפון "<טלפון>", מיקוד "<מיקוד>" + And אני לוחץ "PLACE ORDER" + Then מוצגות שגיאות ספציפיות לכל שדה והמשך התהליך נחסם + And הפוקוס מוצב על השדה הבעייתי הראשון + + Examples: + | אימייל | טלפון | מיקוד | + | userexample.com | 05A12B34C | 1234AB7 | + | user@domain | 052-12A-5678 | 123 | + | user@@example.com | 0521234xyz | 12345678 | + + @ui @TC-F-015 + Scenario: שינוי שפה לאנגלית וחזרה לעברית + Given טופס קופה מלא בערכים + When אני מחליף שפה ל-"English" + Then הטקסטים מתורגמים והכיווניות משתנה ל-LTR + When אני חוזר לעברית + Then הנתונים בטופס נשמרו והכיווניות חוזרת ל-RTL + + @ui @TC-F-016 + Scenario: נגישות – שימוש מלא במקלדת + Given דפדפן תומך מקשים ואלמנטי ממשק נגישים + When אני מנווט עם Tab ל-"SHOP NOW" ומפעיל ב-Enter + And אני מוסיף מוצר לסל ומנווט ל-"View cart" עם Tab + And אני ממשיך לקופה וממלא פרטים באמצעות מקלדת בלבד + And אני לוחץ "PLACE ORDER" באמצעות Enter + Then סדר הפוקוס הגיוני וכל רכיב ניתן לגישה ואין מלכודות פוקוס + + @ui @TC-F-017 + Scenario: התנהגות במצב חוסר מלאי + Given מוצר שהוגדר "Out of stock" פתוח + When אני מנסה להוסיף לסל + Then כפתור הוספה לסל מושבת או מוסתר ומוצגת הודעה "אזל מהמלאי" + + @ui @TC-F-018 + Scenario: כשל רשת במהלך תשלום ושחזור + Given עמוד קופה עם פרטים מלאים + When אני מנתק את הרשת ומייד לוחץ "PLACE ORDER" + Then מוצגת הודעת כשל זמני ידידותית והנתונים נשמרים + When אני משחזר את הרשת ומנסה שוב + Then התהליך מצליח ללא יצירת הזמנות כפולות + + @ui @TC-F-019 + Scenario: התנהגות לאחר לחיצה כפולה על PLACE ORDER + Given עמוד קופה מוכן להגשה ואמצעי תשלום תקף פעיל + When אני לוחץ פעמיים במהירות על "PLACE ORDER" + Then נוצרת הזמנה אחת בלבד והכפתור ננעל או מוצג Spinner לאחר הלחיצה הראשונה + + @ui @TC-F-020 + Scenario: Responsive – ניווט, פאג'ינציה וכפתורים במובייל + Given אמולציית מובייל או מכשיר אמיתי פעיל + When אני פותח את דף הבית במובייל + And אם יש תפריט המבורגר אני פותח אותו ומנווט לקטלוג דרך "SHOP NOW" + And אני עובר לעמוד 2 באמצעות החץ הבא + And אני בוחר "Red Hoodie" ומוסיף לסל + Then כל הכפתורים קריאים, לא קיימת גלילה אופקית והכפתורים ניתנים ללחיצה + + @ui @TC-F-021 + Scenario: בדיקת שינוי מיון קטלוג ושימור בחירה + Given עמוד קטלוג פתוח + When אני בוחר מיון "Price: low to high" + Then סדר כרטיסי המוצרים משתנה בהתאם + When אני נכנס למוצר וחוזר אחורה + Then בחירת המיון נשמרת והסדר נשאר לפי המחיר + + @ui @TC-F-022 + Scenario: בדיקת דירוג מוצר ותצוגת ביקורות + Given דף מוצר פתוח עם אזור ביקורות + When אני גולל לאזור הביקורות + And אם מתאפשר לאורחים אני בוחר 4 כוכבים, מזין תגובה ושולח + Then הביקורת נשמרת ומוצגת עם חיווי כוכבים + But אם נדרש להתחבר מוצגת הודעה שיש להתחבר כדי לדרג + + @ui @TC-F-023 + Scenario: חישוב מע"מ ישראלי והצגת מטבע + Given מיקום החיוב/משלוח מוגדר לישראל והגדרות מס פעילות + When אני מוסיף מוצר לסל ומנווט לקופה + Then המטבע "₪" מוצג בעקביות + And אם מע"מ מופעל מוצגת שורת מע"מ 17% והסכומים תואמים + + @ui @TC-F-024 + Scenario: בדיקת טופס – סימון חובה והבלטת שגיאות + Given דף קופה בעברית פתוח + When אני לוחץ "PLACE ORDER" עם טופס ריק + Then כל שדות החובה מסומנים בצורה ברורה + And מופיע טקסט שגיאה קריא בעברית תחת כל שדה חסר + + @ui @TC-F-025 + Scenario: פונקציית View Cart – ניווט נכון וקריאה לפעולה + Given הוספתי מוצר לסל מדף מוצר וקיבלתי הודעה צפה + When אני לוחץ "VIEW CART" בהודעה + Then עמוד הסל נטען וקיים מסלול חזרה לקניות + + @ui @TC-F-026 + Scenario Outline: בדיקת ריבוי שיטות משלוח ועדכון סכום ותיאור זמן אספקה + Given סל עם פריט אחד פתוח + When אני בוחר שיטת משלוח "<שיטה>" + Then תוספת המשלוח היא "<עלות>" + And מוצג תיאור זמן אספקה "<תיאור>" + + Examples: + | שיטה | עלות | תיאור | + | Local pickup | ₪0 | | + | Delivery Express | ₪12.50 | (1–3 days) | + | Registered Mail | ₪5.90 | (5–8 days) | + + @ui @TC-F-027 + Scenario: השוואת הוספה לסל מול הסרה – סכום כולל חוזר לברירת מחדל + Given סל ריק בתחילת התרחיש + When אני מוסיף "Red Hoodie" ובוחר "Registered Mail" + And אני מסיר את הפריט מהסל + Then הטוטאל מאופס ל-"₪0" ושורת המשלוח מוסרת + + # API Tests (נ infer לפי אינטראקציות קופה/סל/קופון/משלוח) + @api @checkout @TC-F-001 @TC-F-002 + Scenario Outline: ולידציות Checkout ב-API – חסר מיקוד לעומת אמצעי תשלום לא תקין + Given יש לי מזהה סשן אורח ושמור פריט בסל באמצעות POST ל-"/api/cart/items" + And גוף הבקשה להוספת פריט: + """ + { + "product_id": 12345, + "quantity": 1 + } + """ + When אני שולח POST ל-"/api/checkout" עם גוף בקשה: + """ + { + "billing": { + "first_name": "Meital", + "last_name": "Kenzi", + "company": "Menora", + "country": "IL", + "address_1": "Burla yehuda 1", + "address_2": "17", + "city": "Tel Aviv", + "postcode": , + "phone": "0544344345", + "email": "meitalkenzi@gmail.com" + }, + "shipping_method": "registered_mail", + "payment_method": + } + """ + Then קוד התגובה צריך להיות + And גוף התגובה צריך להכיל את ההודעה "" + + Examples: + | postcode | payment_method | status | expected_message | + | null | "bank_transfer"| 400 | Billing Postcode / ZIP is a required field. | + | "316547" | "invalid" | 400 | Invalid payment method | + + @api @coupons @TC-F-007 @TC-F-008 + Scenario Outline: החלת קופון ב-API – הצלחה ושגיאה + Given סל קיים עם פריט אחד באמצעות סשן אורח + When אני שולח POST ל-"/api/coupons/apply" עם גוף: + """ + { + "code": "" + } + """ + Then קוד התגובה צריך להיות + And גוף התגובה צריך להכיל את השדה "" + + Examples: + | code | status | expected_field | + | SALE10 | 200 | discount_amount | + | ABC123 | 400 | error | + + @api @shipping @TC-F-026 + Scenario Outline: עדכון שיטת משלוח ב-API והצלבת סכומים + Given קיים בסל פריט אחד בעל מחיר יחידה 150 ₪ + When אני שולח PUT ל-"/api/cart/shipping" עם גוף: + """ + { + "method": "" + } + """ + Then קוד התגובה צריך להיות 200 + And סכום המשלוח בתגובה הוא "" + + Examples: + | method | shipping_cost | + | local_pickup | ₪0 | + | delivery_express | ₪12.50 | + | registered_mail | ₪5.90 | + + @api @orders @TC-F-009 + Scenario: יצירת הזמנה תקינה ב-API + Given סל קיים עם פריט אחד ושיטת משלוח "local_pickup" + When אני שולח POST ל-"/api/orders" עם גוף: + """ + { + "billing": { + "first_name": "Dana", + "last_name": "Cohen", + "country": "IL", + "address_1": "Yehuda Halevi 10", + "city": "Tel Aviv", + "postcode": "6473421", + "phone": "0521234567", + "email": "dana@example.com" + }, + "payment_method": "bank_transfer", + "confirm": true + } + """ + Then קוד התגובה צריך להיות 201 + And גוף התגובה צריך להכיל "order_id" ו-"status"="processing" + + @api @cart @TC-F-010 + Scenario: התמדה של סל ב-API באמצעות סשן + Given הוספתי פריט לסל עם מזהה סשן X + When אני שולח GET ל-"/api/cart" עם כותרת "X-Session-Id: X" + Then קוד התגובה צריך להיות 200 + And הגוף מכיל את הפריט שנוסף קודם + + # Non-Functional Tests + @nonfunctional @performance @TC-NF-001 + Scenario Outline: ביצועים – זמני טעינה ותגובה בתהליך רכישה + Given מצב רשת 4G סטנדרטי מוגדר בכלי המדידה + When אני מודד את "<מדד>" עבור "<מסך/פעולה>" + Then התוצאה צריכה להיות קטנה מ-<סף> שניות + + Examples: + | מדד | מסך/פעולה | סף | + | TTI | דף הבית | 3 | + | זמן| לחיצה "Add to cart" עד הודעת הצלחה | 1.5| + | זמן| טעינת דף הקופה | 2 | + + @nonfunctional @load @TC-NF-002 + Scenario: סקיילביליות – עומס משתמשים בו-זמנית + Given תרחיש עומס ב-JMeter: כניסה → קטלוג → Add to cart → View cart → Checkout + When אני מריץ עומס מדורג 50 → 100 → 300 משתמשים בו-זמנית + Then שיעור שגיאות < 1% וזמני תגובה יציבים או דגרדציה נשלטת ללא קריסות + + @nonfunctional @security @TC-NF-003 + Scenario: אבטחה – TLS, HSTS, Cookie Flags ו-CSRF + Given אני מריץ סריקת SSL Labs לאתר + When אני בודק כותרות HTTP ל-HSTS, Cookie Secure/HttpOnly/SameSite + And אני מאמת קיום nonce/CSRF בטפסי "Add to cart"/"Checkout" + Then הדירוג הוא A, אין העברת PII ב-HTTP ומנגנוני CSRF פעילים + + @nonfunctional @privacy @TC-NF-004 + Scenario: פרטיות – מדיניות פרטיות והסכמות + Given עמוד "privacy policy" קיים ונגיש בקופה + When אני פותח את הקישור ובוחן שימוש ב-PII והעברות לצד ג' + Then המדיניות ברורה, אין איסוף מיותר וקיימות דרכי יצירת קשר למימוש זכויות + + @nonfunctional @pci @TC-NF-005 + Scenario: אבטחת תשלומים – ציות ל-PCI DSS + Given סביבת סנדבוקס של ספק תשלום פעילה + When אני מאמת שטפסי תשלום נטענים מדומיין הספק (Iframe/Redirect) ואין אחסון PAN באתר + And אני בודק שלוגים אינם מכילים PII/פרטי כרטיס + Then אין דליפת נתונים והודעות שגיאה אינן חושפות מידע רגיש + + @nonfunctional @reliability @TC-NF-006 + Scenario: אמינות – התמדה של סל לאחר timeout/ניתוק + Given סל עם פריטים קיים + When אני ממתין 30–45 דקות ללא פעילות ומרענן דף + Then הסל עדיין קיים או מוצגת הודעה מתאימה על פקיעת סשן + + @nonfunctional @accessibility @TC-NF-007 + Scenario: נגישות – תאימות WCAG 2.1 AA + Given התקנתי axe/WAVE בדפדפן + When אני סורק דף הבית, קטלוג, מוצר וקופה + Then אין כשלים קריטיים, לכל תמונה Alt, לכל שדה תווית, ויחס ניגודיות ≥ 4.5:1 + + @nonfunctional @compatibility @TC-NF-008 + Scenario Outline: התאמה בין דפדפנים ומערכות הפעלה + Given דפדפן "<דפדפן>" על פלטפורמה "<פלטפורמה>" פעיל + When אני מבצע את התסריט TC-F-001 מקצה לקצה + Then ההתנהגות אחידה וללא שברים פריסתיים + + Examples: + | דפדפן | פלטפורמה | + | Chrome | Windows | + | Firefox | Windows | + | Edge | Windows | + | Safari | iOS | + | Chrome | Android | + + @nonfunctional @logging @TC-NF-009 + Scenario: ניטור ולוגים – תיעוד עסקאות ושגיאות + Given גישה ללוגי השרת/יישום + When אני מבצע הזמנה מוצלחת והזמנה כושלת + Then בלוגים מופיעים מזהה הזמנה, מזהה סשן וסטטוס תשלום ללא PII מלא ועם יכולת קורלציה + + @nonfunctional @thirdparty @TC-NF-010 + Scenario: התאוששות מכשל שירות צד-שלישי (Gateway 5xx) + Given יכולת לדמות כשל 503 ב-Gateway תשלום + When אני מנסה "PLACE ORDER" בזמן הכשל + Then לא נוצרת הזמנה ומוצגת הודעת שגיאה ידידותית + When השירות חוזר ואני מנסה שוב + Then נוצרת הזמנה אחת בלבד + + @nonfunctional @security @xss @TC-NF-011 + Scenario: מניעת XSS/Injection בשדות הכתובת + Given עמוד קופה פתוח + When אני מזין בשדה "Company" את הטקסט "" ומגיש + Then לא מתבצעת הרצת סקריפט והטקסט מוצג כטקסט/מסונן בכל התצוגות + + @nonfunctional @privacy @referrer @TC-NF-012 + Scenario: מניעת דליפת פרטי לקוח ב-Referrer + Given DevTools פתוח בלשונית Network + When אני נווט לקישור חיצוני (למשל ספק תשלום) + Then כותרת 'Referer' אינה מכילה PII ומוגדרת מדיניות Strict-Origin-When-Cross-Origin או דומה + + @nonfunctional @i18n @TC-NF-013 + Scenario: יציבות RTL/LTR במעבר בין שפות + Given מתג שפה פעיל באתר + When אני עובר לאנגלית ובודק שהמטבע "₪" נשאר + And אני חוזר לעברית ובודק שהפאג'ינציה מיושרת לימין + Then אין שבירת UI והמטבע נשאר "₪" בכל שפה diff --git a/functional_tests/roost_test_1766048227/roost_test_1766048227.json b/functional_tests/roost_test_1766048227/roost_test_1766048227.json new file mode 100644 index 0000000..b7f8ac3 --- /dev/null +++ b/functional_tests/roost_test_1766048227/roost_test_1766048227.json @@ -0,0 +1,406 @@ +{ + "scenarios": [ + { + "type": "functional", + "title": "מסע רכישה מלא – מהבאנר הראשי ועד ולידציות בקופה", + "description": "אימות תהליך קנייה מקצה לקצה בהתאם לתסריט המבוקש: כניסה דרך SHOP NOW, מעבר לעמוד 2, בחירת Red Hoodie, הוספה לסל, בחירת שיטות משלוח, מעבר לקופה, מילוי פרטים, שגיאת מיקוד ושגיאת אמצעי תשלום.", + "testId": "TC-F-001", + "testDescription": "כמשתמש אורח, אני רוצה לרכוש מוצר דרך דף הבית כדי לוודא שתהליך הקנייה, הוולידציות והשגיאות מוצגות נכון בעברית ובפורמט מקומי.", + "prerequisites": "דפדפן כרום עדכני במובייל/דסקטופ. כתובת האתר פעילות. סל קניות ריק. חיבור אינטרנט תקין.", + "stepsToPerform": "1. היכנס ל-URL שסופק.\n2. לחץ על הכפתור 'SHOP NOW' בבאנר 'Latest Eyewear For You'.\n3. גלול לתחתית עמוד הקטגוריה ועבור לעמוד מס' 2 באמצעות לחיצה על החץ 'הבא'.\n4. בדף התוצאות בחר את המוצר 'Red Hoodie' באמצעות לחיצה על התמונה או על שם המוצר.\n5. בדף המוצר לחץ 'ADD TO CART'.\n6. בהודעת ההוספה לסל לחץ 'VIEW CART'.\n7. בסל סמן לפי הסדר: Local pickup → Delivery Express → Registered Mail, ואמת שהעלות הכוללת מתעדכנת בהתאם (₪12.50 למשלוח מהיר, ₪5.90 לדואר רשום, ₪0 לאיסוף מקומי במידה שמסומן).\n8. לחץ 'PROCEED TO CHECKOUT'.\n9. בקופה הזן: First name=Meital, Last name=Kenzi, Company=Menora (אופציונלי), Country=Israel, Street address='Burla yehuda 1', Apartment/Unit='17', Town/City='Tel Aviv,', Phone='0544344345', Email='meitalkenzi@gmail.com'. השאר Postcode/ZIP ריק.\n10. לחץ 'PLACE ORDER'.", + "expectedResult": "ולידציה 1: מוצגת הודעת שגיאה בעברית/אנגלית ברורה באזור ההודעות: 'Billing Postcode / ZIP is a required field.'. אין יצירת הזמנה.", + "postConditions": "המשתמש נשאר בעמוד התשלום עם שדות שמורים. אין חיוב ואין יצירת הזמנה." + }, + { + "type": "functional", + "title": "המשך התסריט – הזנת מיקוד וקבלת שגיאת אמצעי תשלום", + "description": "המשך מתוך TC-F-001 לאחר קבלת שגיאת מיקוד, הזנת מיקוד ולידציה לשגיאת אמצעי תשלום.", + "testId": "TC-F-002", + "testDescription": "כמשתמש אורח לאחר ניסיון תשלום, אני מזין מיקוד ומוודא שהמערכת מזהה היעדר/אי-תקינות אמצעי תשלום ומציגה הודעה מתאימה.", + "prerequisites": "המשך מצב מהשלב האחרון של TC-F-001 (בקופה, כל השדות מלאים חוץ מהמיקוד).", + "stepsToPerform": "1. הזן בשדה Postcode/ZIP את הערך '316547'.\n2. לחץ 'PLACE ORDER' מחדש.", + "expectedResult": "ולידציה 2: מוצגת הודעת שגיאה 'Invalid payment method'. אין יצירת הזמנה.", + "postConditions": "הזמנה לא נוצרה. המשתמש נשאר בדף הקופה עם נתונים שמורים ומיקוד מוזן." + }, + { + "type": "functional", + "title": "מעבר לעמוד מס' 2 באמצעות לחיצה על הספרה 2", + "description": "אימות אלטרנטיבה למעבר בין עמודי קטלוג.", + "testId": "TC-F-003", + "testDescription": "כמשתמש, אני רוצה לנווט לעמוד 2 באמצעות לחיצה על מספר העמוד כדי להגיע למוצר המבוקש.", + "prerequisites": "דף קטלוג פתוח (לאחר לחיצה על SHOP NOW).", + "stepsToPerform": "1. בתחתית הקטלוג לחץ על '2'.\n2. אמת כי הטקסט 'Showing 13–14 of 14 results' או אינדיקציה מתאימה לעמוד 2 מוצגים.", + "expectedResult": "העמוד מדפיס תוצאות של עמוד 2. הניווט פעיל והספרה '2' מסומנת." + }, + { + "type": "functional", + "title": "כניסה למוצר באמצעות שם המוצר לעומת התמונה", + "description": "ווידוא ששני אלמנטים מובילים לדף המוצר.", + "testId": "TC-F-004", + "testDescription": "כמשתמש, יש לי שתי דרכים לגשת לדף מוצר – דרך התמונה ודרך כותרת המוצר.", + "prerequisites": "עמוד 2 של הקטלוג פתוח.", + "stepsToPerform": "1. לחץ על שם המוצר 'Red Hoodie' ואמת מעבר לדף המוצר.\n2. חזור לעמוד 2.\n3. לחץ על תמונת 'Red Hoodie' ואמת מעבר לדף המוצר.", + "expectedResult": "בשני המקרים נטען דף המוצר עם כותרת 'Red Hoodie' ונתיב פירורי לחם מתאים: Home / Men / Red Hoodie." + }, + { + "type": "functional", + "title": "הוספה לסל מדף הקטלוג (אם כפתור זמין)", + "description": "אימות הוספה מהירה לסל וחיווי הצלחה.", + "testId": "TC-F-005", + "testDescription": "כמשתמש, אני מעוניין להוסיף מוצר לסל ישירות מדף הקטלוג כדי לייעל את תהליך הרכישה.", + "prerequisites": "כפתור 'Add to cart' זמין בכרטיס המוצר בעמוד הקטלוג.", + "stepsToPerform": "1. לחץ 'Add to cart' על 'Red Hoodie'.\n2. אמת הופעת toast/הודעת מערכת שהמוצר נוסף.\n3. לחץ 'VIEW CART' בהודעה.", + "expectedResult": "המוצר מופיע בסל, הכמות=1, המחיר 150.00 ₪, המטבע מוצג כ-₪." + }, + { + "type": "functional", + "title": "עדכון כמויות וחישוב עלויות משלוח", + "description": "בדיקת עדכון סל והשלכה על סכום כולל כולל משלוח.", + "testId": "TC-F-006", + "testDescription": "כקונה, אני רוצה לשנות את הכמות בסל ולראות את ההשפעה על הסכום הכולל ועלויות המשלוח בזמן אמת.", + "prerequisites": "סל עם 'Red Hoodie' כמות 1.", + "stepsToPerform": "1. שנה כמות ל-2 ולחץ 'Update cart' אם נדרש.\n2. בחר 'Delivery Express' ואמת תוספת ₪12.50.\n3. החלף ל-'Registered Mail' ואמת שהמשלוח מתעדכן ל-₪5.90.\n4. החלף ל-'Local pickup' ואמת משלוח ₪0.", + "expectedResult": "הסכום הכולל = מחיר פריטים (2×150=300 ₪) + מחיר משלוח שנבחר. כל שינוי משלוח מעדכן את הטוטאל מידית." + }, + { + "type": "functional", + "title": "יישום קופון תקף", + "description": "הנחה מחושבת ומוצגת בסל/בקופה בהתאם לכללי הקופון.", + "testId": "TC-F-007", + "testDescription": "כקונה, אני רוצה להחיל קופון כדי לקבל הנחה ולוודא חישוב נכון של הטוטאל במטבע ₪ כולל מע\"מ ישראלי.", + "prerequisites": "קופון תקף קיים במערכת (לדוגמה: 'SALE10' – 10% הנחה). סל עם מוצר אחד לפחות.", + "stepsToPerform": "1. לחץ 'Have a coupon? Click here to enter your code'.\n2. הזן 'SALE10' ולחץ 'Apply coupon'.", + "expectedResult": "מוצגת שורת קופון עם סכום הנחה. סכום סופי מתעדכן ומוצג במטבע ₪. הודעת הצלחה מוצגת." + }, + { + "type": "functional", + "title": "קופון לא תקף/פג תוקף", + "description": "ווידוא הודעת שגיאה ברורה ופעולת שחזור.", + "testId": "TC-F-008", + "testDescription": "כקונה, אם אני מזין קוד לא קיים/פג תוקף, אני רוצה להבין מה הבעיה וכיצד לפעול.", + "prerequisites": "סל עם פריט.", + "stepsToPerform": "1. פתח אזור קופון.\n2. הזן 'ABC123' ולחץ 'Apply coupon'.", + "expectedResult": "מוצגת הודעת שגיאה ידידותית למשתמש (בעברית אם האתר בעברית) ובלי שינוי בסכום הכולל." + }, + { + "type": "functional", + "title": "תהליך הזמנה מוצלח עם אמצעי תשלום זמין", + "description": "תסריט חיובי מלא עד עמוד אישור הזמנה.", + "testId": "TC-F-009", + "testDescription": "כקונה, אני רוצה להשלים רכישה עם אמצעי תשלום זמין (למשל 'תשלום במזומן בעת איסוף' או 'העברה בנקאית') כדי לקבל מספר הזמנה וקבלה.", + "prerequisites": "מוגדר לפחות אמצעי תשלום אחד פעיל במערכת WooCommerce. סל עם פריט אחד. כתובת במדינת ישראל.", + "stepsToPerform": "1. מסל הקניות לחץ 'PROCEED TO CHECKOUT'.\n2. מלא את כל פרטי החיוב כולל מיקוד בן 7 ספרות תקין לדוגמה '6473421'.\n3. בחר שיטת משלוח 'Local pickup'.\n4. בחר את אמצעי התשלום הזמין ('Direct Bank Transfer' או 'Cash on Delivery').\n5. סמנו שהנכם מסכימים למדיניות אם נדרש.\n6. לחץ 'PLACE ORDER'.", + "expectedResult": "מוצג עמוד אישור הזמנה עם מספר הזמנה. מתקבל מייל אישור לכתובת שהוזנה. אין הודעות שגיאה." + }, + { + "type": "functional", + "title": "שמירת סל לאחר רענון/ניווט חזרה", + "description": "התמדה של נתוני הסל בין טעינות וניווט.", + "testId": "TC-F-010", + "testDescription": "כקונה, אני מצפה שהפריטים בסל יישמרו גם אם רעננתי את הדף או חזרתי לדף הבית.", + "prerequisites": "סל עם פריט אחד לפחות.", + "stepsToPerform": "1. רענן את דף הסל (F5).\n2. נווט לדף הבית ואז חזור לסל.\n3. סגור את הדפדפן, פתח מחדש את האתר וחזור לסל (באותו התקן ודפדפן).", + "expectedResult": "הפריטים נשמרים בסל לאורך כל הפעולות." + }, + { + "type": "functional", + "title": "הסרת פריט מהסל", + "description": "אימות חישוב מחדש של סכום והודעות משתמש.", + "testId": "TC-F-011", + "testDescription": "כקונה, כשאני מסיר פריט מהסל אני רוצה לראות שהסכום מתעדכן והסל עשוי להיות ריק.", + "prerequisites": "סל עם לפחות פריט אחד.", + "stepsToPerform": "1. לחץ על האייקון 'X' ליד הפריט בסל.\n2. אמת הודעת 'Cart updated' אם קיימת.", + "expectedResult": "הפריט נמחק והסכום הכולל מתעדכן. אם הסל ריק – מוצג כפתור 'Return to shop'." + }, + { + "type": "functional", + "title": "בדיקת Breadcrumbs וניווט חזרה לקטגוריה", + "description": "ווידוא עקיבות הניווט.", + "testId": "TC-F-012", + "testDescription": "כמשתמש, אני רוצה להשתמש בפירורי לחם כדי לחזור לקטגוריית Men.", + "prerequisites": "דף מוצר פתוח.", + "stepsToPerform": "1. בדף 'Red Hoodie' לחץ על 'Men' ב-Breadcrumbs.\n2. אמת הגעה לקטגוריית Men.", + "expectedResult": "המערכת מנווטת לעמוד הקטגוריה הנכון." + }, + { + "type": "functional", + "title": "הזנת פרטי חיוב בעברית ו-RTL", + "description": "בדיקת טפסים ותמיכה בכיווניות ימין-לשמאל.", + "testId": "TC-F-013", + "testDescription": "כקונה דובר עברית, אני מזין פרטים בעברית ומוודא מיושרות נכונה, סימון שדות חובה, והודעות שגיאה בעברית.", + "prerequisites": "שפת האתר: עברית.", + "stepsToPerform": "1. מלא שם פרטי=\"דנה\", שם משפחה=\"כהן\", רחוב=\"יהודה הלוי 10\", עיר=\"תל אביב\", מיקוד=\"6473421\", טלפון=\"0521234567\", אימייל=\"dana@example.com\".\n2. לחץ 'PLACE ORDER' (עם אמצעי תשלום תקף אם קיים).", + "expectedResult": "אין בעיות כיווניות/יישור. שדות עברית מוצגים נכון. אם חסר מידע – הודעות בעברית ומיקוד פוקוס לשדה הבעייתי." + }, + { + "type": "functional", + "title": "ולידציות שדות – אימייל/טלפון/מיקוד לא חוקיים", + "description": "בדיקת טיפול בנתונים לא תקינים והודעות ידידותיות.", + "testId": "TC-F-014", + "testDescription": "כקונה, אם אני מזין ערכים שגויים (אימייל ללא '@', טלפון עם אותיות, מיקוד שאינו מספרי או לא 7 ספרות), המערכת צריכה למנוע המשך ולהציג מסרים ברורים.", + "prerequisites": "דף קופה פתוח.", + "stepsToPerform": "1. אימייל='userexample.com', טלפון='05A12B34C', מיקוד='1234AB7'.\n2. לחץ 'PLACE ORDER'.", + "expectedResult": "המערכת מציגה שגיאות ספציפיות לכל שדה, מונעת המשך, וממקמת פוקוס על השדה הראשון הבעייתי." + }, + { + "type": "functional", + "title": "שינוי שפה לאנגלית וחזרה לעברית", + "description": "בדיקת יציבות נתונים בשינוי שפה ו-RTL/LTR.", + "testId": "TC-F-015", + "testDescription": "כמשתמש, אני מחליף שפה דרך מתג השפות/Google Translate כדי לוודא שהערכים שהוזנו בטופס אינם נמחקים והכיווניות מתעדכנת.", + "prerequisites": "טופס קופה עם שדות מלאים.", + "stepsToPerform": "1. החלף לשפה 'English'.\n2. אמת שהטקסטים מתורגמים והכיווניות LTR.\n3. חזור לעברית.\n4. אמת שהנתונים בטופס נשמרו.", + "expectedResult": "הטופס שומר ערכים. כיווניות וטקסטים מתעדכנים בהתאם." + }, + { + "type": "functional", + "title": "נגישות – שימוש מלא במקלדת", + "description": "בדיקת אפשרות לבצע את תהליך הקנייה ללא עכבר.", + "testId": "TC-F-016", + "testDescription": "כמשתמש הזקוק לנגישות, אני רוצה לעבור בין שדות הכפתורים (SHOP NOW, Add to cart, View cart, Proceed to checkout, Place order) באמצעות מקשי Tab/Enter/Space.", + "prerequisites": "תוסף הנגישות גלוי במסך. דפדפן תומך.", + "stepsToPerform": "1. מנקודת ההתחלה, נווט באמצעות Tab ל-'SHOP NOW' והפעל ב-Enter.\n2. הוסף מוצר לסל ונווט לסל באמצעות Tab.\n3. המשך לקופה ומלא פרטים באמצעות מקלדת בלבד.\n4. לחץ 'PLACE ORDER' ב-Enter.", + "expectedResult": "סדר פוקוס הגיוני, כל רכיב נגיש, אין מלכודות פוקוס. לא נדרשת עכבר." + }, + { + "type": "functional", + "title": "התנהגות במצב חוסר מלאי", + "description": "בדיקת תצוגה ומניעת הוספה לסל כשאין מלאי.", + "testId": "TC-F-017", + "testDescription": "כקונה, אם מוצר לא זמין במלאי, המערכת צריכה להציג סטטוס 'אזל מהמלאי' ולמנוע קניה.", + "prerequisites": "מוצר בדיקה שמוגדר Out of stock או סימולציה.", + "stepsToPerform": "1. פתח מוצר אזל מהמלאי.\n2. נסה להוסיף לסל.", + "expectedResult": "כפתור הוספה לסל מושבת/מוסתר. הודעה ברורה מוצגת." + }, + { + "type": "functional", + "title": "כשל רשת במהלך תשלום ושחזור", + "description": "בדיקת שרידות התהליך והודעת שחזור/ניסיון חוזר.", + "testId": "TC-F-018", + "testDescription": "כקונה, אם הרשת נופלת בזמן 'PLACE ORDER', אני רוצה הודעת שגיאה ידידותית ושמירת נתוני הטופס.", + "prerequisites": "דף קופה עם פרטים מלאים.", + "stepsToPerform": "1. נתק את הרשת לפני לחיצה על 'PLACE ORDER'.\n2. לחץ 'PLACE ORDER'.\n3. שחזר את הרשת.\n4. נסה שוב.", + "expectedResult": "הודעת כשל זמני מוצגת. הנתונים נשמרים. ניתן לנסות שוב בהצלחה." + }, + { + "type": "functional", + "title": "התנהגות לאחר לחיצה כפולה על PLACE ORDER", + "description": "מניעת הזמנות כפולות באמצעות מנגנון Idempotency.", + "testId": "TC-F-019", + "testDescription": "כקונה, אם לחצתי פעמיים במהירות על 'PLACE ORDER', לא ייווצרו שתי הזמנות.", + "prerequisites": "אמצעי תשלום תקף פעיל או סביבת סנדבוקס.", + "stepsToPerform": "1. מלא את הטופס במלואו.\n2. לחץ פעמיים מהר על 'PLACE ORDER'.", + "expectedResult": "נוצרת הזמנה אחת בלבד. הכפתור ננעל לאחר הלחיצה הראשונה/מופיע Spin Loader." + }, + { + "type": "functional", + "title": "Responsive – ניווט, פאג'ינציה וכפתורים במובייל", + "description": "בדיקת חוויית משתמש במסכים קטנים.", + "testId": "TC-F-020", + "testDescription": "כמשתמש מובייל, אני רוצה להגיע לעמוד 2, לבחור מוצר ולהוסיף לסל כאשר כל הכפתורים נגישים וקריאים.", + "prerequisites": "אמולציית מובייל (iPhone/Android) או מכשיר אמיתי.", + "stepsToPerform": "1. פתח את דף הבית במובייל.\n2. לחץ על תפריט/אייקון המבורגר אם נדרש והמשך לקטלוג דרך SHOP NOW.\n3. עבור לעמוד 2 באמצעות החץ.\n4. בחר 'Red Hoodie' והוסף לסל.\n5. אמת שהכפתורים אינם חורגים מהמסך וקריאים.", + "expectedResult": "כל הרכיבים מותאמים, ללא גלילה אופקית, כפתורים ניתנים ללחיצה." + }, + { + "type": "functional", + "title": "בדיקת שינוי מיון קטלוג ושימור בחירה", + "description": "אימות שהמיון משנה את סדר התוצאות ונשמר בניווט אחורה/קדימה.", + "testId": "TC-F-021", + "testDescription": "כמשתמש, אני בוחר מיון 'Price: low to high' ובודק שהבחירה נשמרת.", + "prerequisites": "עמוד קטלוג פתוח.", + "stepsToPerform": "1. פתח תיבת המיון ובחר 'Price: low to high'.\n2. אמת שינוי סדר כרטיסי המוצרים.\n3. נווט למוצר וחזור אחורה.", + "expectedResult": "הבחירה נשמרת והסדר נשאר לפי המחיר." + }, + { + "type": "functional", + "title": "בדיקת דירוג מוצר ותצוגת ביקורות", + "description": "הוספת דירוג חדש (אם אפשר אורחים) או צפייה בביקורות קיימות.", + "testId": "TC-F-022", + "testDescription": "כמשתמש, אני רוצה לראות ולתת דירוג כדי לסייע לאחרים בקנייה.", + "prerequisites": "דף מוצר פתוח. הרשאות בהתאם למדיניות (אורחים/מחוברים).", + "stepsToPerform": "1. גלול לאזור הביקורות.\n2. אם אפשר – בחר 4 כוכבים, הזן תגובה ושלח.\n3. אחרת – אמת שתוצג הערה שיש להתחבר כדי לדרג.", + "expectedResult": "ביקורת נשמרת ומוצגת עם חיווי כוכבים או הודעה מתאימה." + }, + { + "type": "functional", + "title": "חישוב מע\"מ ישראלי והצגת מטבע", + "description": "וידוא הצגת מחירים ב-₪ כולל/ללא מע\"מ בהתאם להגדרות.", + "testId": "TC-F-023", + "testDescription": "כקונה בישראל, אני מצפה למחירים במטבע ₪ ולתמחור הכולל מע\"מ 17% אם מוגדר להציגו.", + "prerequisites": "מיקום חשבון/משלוח ישראל. הגדרות מס פעילות אם קיימות.", + "stepsToPerform": "1. הוסף מוצר לסל.\n2. עבור לקופה ובדוק את פירוט הסכומים.", + "expectedResult": "מטבע ₪ מוצג עקבי. אם מע\"מ מופעל – מוצגת שורת מע\"מ עם שיעור 17% והסכומים תואמים." + }, + { + "type": "non-functional", + "title": "ביצועים – זמני טעינה ותגובה בתהליך רכישה", + "description": "מדידת זמני טעינה בדסקטופ ובמובייל על גבי 4G.", + "testId": "TC-NF-001", + "testDescription": "כאחראי ביצועים, אני רוצה לוודא שהדף הראשי נטען < 3 שניות, הוספה לסל < 1.5 שניות, מעבר לקופה < 2 שניות.", + "prerequisites": "כלי מדידה (Lighthouse/WebPageTest). מצב רשת 4G סטנדרטי.", + "stepsToPerform": "1. מדוד זמן ל-TTI בדף הבית.\n2. מדוד זמן מרגע לחיצה על 'Add to cart' עד להופעת הודעת הצלחה.\n3. מדוד זמן טעינת דף הקופה.", + "expectedResult": "כל המדדים עומדים ביעדים שהוגדרו." + }, + { + "type": "non-functional", + "title": "סקיילביליות – עומס משתמשים בו-זמנית", + "description": "בדיקת ביצועים תחת עומס קונים במקביל.", + "testId": "TC-NF-002", + "testDescription": "כבודק עומסים, אני מריץ 100–300 משתמשים בו-זמנית שמבצעים הוספה לסל ומעבר לקופה כדי לוודא זמן תגובה יציב והתנהגות graceful degradation.", + "prerequisites": "JMeter/Gatling. סביבת בדיקות מבודדת.", + "stepsToPerform": "1. ספק תסריט: כניסה → קטלוג → Add to cart → View cart → Checkout.\n2. העלה עומס מדורג: 50 → 100 → 300 משתמשים.\n3. מדוד שיעור שגיאות וזמן תגובה.", + "expectedResult": "שיעור שגיאות < 1%. זמני תגובה נשמרים או דגרדציה נשלטת ללא קריסות." + }, + { + "type": "non-functional", + "title": "אבטחה – תקשורת מוצפנת וניהול סשן", + "description": "עמידה ב-TLS 1.2+, HSTS, HttpOnly/Secure/SameSite לקוקיות, CSRF ב-Checkout.", + "testId": "TC-NF-003", + "testDescription": "כאיש אבטחה, אני בודק שכפייה ל-HTTPS פעילה, HSTS מוגדר, csrf nonce קיים בטפסי 'Add to cart'/'Checkout', וקוקיות מוגדרות כ-Secure, HttpOnly ו-SameSite=Lax/Strict.", + "prerequisites": "כלי אבטחה: OWASP ZAP/Qualys SSL Labs.", + "stepsToPerform": "1. סריקת SSL Labs לאתר.\n2. בדוק תגובות HTTP headers.\n3. אמת נוכחות nonce/CSRF בשדות הטפסים.", + "expectedResult": "דירוג אבטחה A. אין העברת PII ב-HTTP. מגנות CSRF קיימות." + }, + { + "type": "non-functional", + "title": "פרטיות ורגולציה – חוק הגנת הפרטיות הישראלי", + "description": "בדיקת שימוש ב-PII, מדיניות פרטיות והסכמות.", + "testId": "TC-NF-004", + "testDescription": "כבודק ציות, אני מוודא שהאתר מציג מדיניות פרטיות בעברית, מסביר שימוש בנתונים לעיבוד הזמנה, ושקיימת עמידה לתקנות אבטחת מידע 2017 (ישראל).", + "prerequisites": "דף 'privacy policy' קיים.", + "stepsToPerform": "1. פתח קישור privacy policy בקופה.\n2. אמת הסבר ברור לשימוש בנתונים והעברות לצד ג'.\n3. בדוק אפשרות בקשה למחיקה/תיקון נתונים (זכות לעיון).", + "expectedResult": "מדיניות ברורה, קישור נגיש, אין איסוף מיותר, קיימות דרכי יצירת קשר למימוש זכויות." + }, + { + "type": "non-functional", + "title": "אבטחת תשלומים – ציות ל-PCI DSS/הנחיות בנק ישראל", + "description": "אין שמירת פרטי כרטיס באתר בדיקות, שימוש ב-Gateway תואם ו-Tokenization.", + "testId": "TC-NF-005", + "testDescription": "כאיש ציות פיננסי, אני בודק שאמצעי התשלום (אם כרטיס אשראי קיים) מנוהל ע\"י ספק מאושר PCI, שאין שדות כרטיס מקומיים ללא tokenization, ושקיימות הודעות שגיאה ידידותיות (כגון 'Invalid payment method').", + "prerequisites": "גישה לסביבת סנדבוקס של ספק התשלום (אם קיים).", + "stepsToPerform": "1. בדוק שהמסכים נטענים מ-Domain של ספק התשלום (Iframe/Redirect) ולא מאחסנים PAN.\n2. אמת שאין לוגים עם PII/פרטי כרטיס.\n3. בצע תשלום ניסוי ובדוק מסרים.", + "expectedResult": "עמידה ב-PCI DSS. אין דליפת פרטי כרטיס. הודעות שגיאה אינן חושפות מידע רגיש." + }, + { + "type": "non-functional", + "title": "אמינות – התמדה של סל לאחר timeout/ניתוק", + "description": "בדיקת שמירת סל בצד לקוח/שרת לאחר פקיעת סשן.", + "testId": "TC-NF-006", + "testDescription": "כבודק אמינות, אני בודק שהסל נשמר גם לאחר 30 דק' חוסר פעילות ושחזור הסשן.", + "prerequisites": "סל עם פריטים.", + "stepsToPerform": "1. הוסף פריטים לסל.\n2. המתן 30–45 דק' ללא פעילות.\n3. רענן את הדף.", + "expectedResult": "הסל עדיין קיים. אם לא – מוצגת הודעה מתאימה." + }, + { + "type": "non-functional", + "title": "נגישות – תאימות WCAG 2.1 AA", + "description": "בדיקת ניגודיות, טקסט חלופי לתמונות, כותרות ARIA וטפסים מתויגים.", + "testId": "TC-NF-007", + "testDescription": "כבודק נגישות, אני מריץ axe/WAVE ובודק שאין כשלים קריטיים. אייקון הנגישות לא חוסם שדות והניווט תקין.", + "prerequisites": "תוספי בדיקות נגישות בדפדפן.", + "stepsToPerform": "1. סריקה בדף הבית, קטלוג, מוצר וקופה.\n2. בדיקת Alt לתמונות מוצר. תוויות לשדות טופס.\n3. בדיקת contrast (יחס ≥ 4.5:1 לטקסט רגיל).", + "expectedResult": "ללא שגיאות קריטיות. אפשר להשלים את התהליך במקלדת ועוזרות נגישות." + }, + { + "type": "non-functional", + "title": "התאמה בין דפדפנים ומערכות הפעלה", + "description": "בדיקת תאימות כרום, פיירפוקס, Edge, Safari (iOS), כרום אנדרואיד.", + "testId": "TC-NF-008", + "testDescription": "כבודק תאימות, אני מוודא שכל רכיבי התהליך פועלים זהה בכל הדפדפנים והגדלים הנפוצים בישראל.", + "prerequisites": "מכשירים/אמולטורים זמינים.", + "stepsToPerform": "1. בצע את התסריט TC-F-001 בכל דפדפן/מכשיר.\n2. תעד הבדלי UI/פונקציונליות.", + "expectedResult": "התנהגות אחידה. ללא שברים פריסתיים." + }, + { + "type": "non-functional", + "title": "ניטור ולוגים – תיעוד עסקאות ושגיאות", + "description": "בדיקת התכנות לכללים: לוגים ללא PII מלא, זיהוי שגיאות תשלום.", + "testId": "TC-NF-009", + "testDescription": "כמפעיל מערכת, אני רוצה לוגים עם מזהה הזמנה, מזהה משתמש/סשן, סטטוס תשלום, ללא חשיפת נתוני כרטיס, כדי לאפשר חקירה מהירה.", + "prerequisites": "גישה ללוגי השרת/יישום.", + "stepsToPerform": "1. בצע הזמנה מוצלחת וכושלת.\n2. בדוק ערכי לוגים (INFO/ERROR).\n3. אמת שאין PII מיותר.", + "expectedResult": "לוגים תמציתיים, ללא דליפת מידע, כוללים קורלציה לטרייסים." + }, + { + "type": "non-functional", + "title": "התאוששות מכשל שירות צד-שלישי (Gateway/משלוחים)", + "description": "בדיקת Failover/Retry כאשר ה-Gateway מחזיר 5xx.", + "testId": "TC-NF-010", + "testDescription": "כבודק אמינות, אני מדמה כשל זמני ב-Gateway ומוודא שהמשתמש מקבל הודעה ידידותית ואפשרות לנסות שוב ללא כפילות הזמנה.", + "prerequisites": "יכולת לדמות כשל API בסביבת בדיקות.", + "stepsToPerform": "1. נסה לבצע 'PLACE ORDER' בזמן שה-Gateway מחזיר 503.\n2. לאחר זמן קצר החזר את השירות ונסה שוב.", + "expectedResult": "אין הזמנה בזמן הכשל, הודעת שגיאה ידידותית. בלחיצה נוספת לאחר התאוששות נוצרת הזמנה אחת." + }, + { + "type": "functional", + "title": "בדיקת טופס – סימון חובה והבלטת שגיאות", + "description": "התנהגות UI ידידותית: קו אדום/אייקון/טקסט מתחת לשדה.", + "testId": "TC-F-024", + "testDescription": "כמשתמש, אני רוצה לראות סמן ברור לשדות שחייבים מילוי ומסרים תמציתיים מתחת לשדה (לדוגמה 'שדה זה חובה').", + "prerequisites": "דף קופה בעברית.", + "stepsToPerform": "1. לחץ 'PLACE ORDER' עם טופס ריק.\n2. צפה בשדות חובה המסומנים.", + "expectedResult": "כל שדות חובה מסומנים. מופיע טקסט שגיאה קריא בעברית." + }, + { + "type": "functional", + "title": "פונקציית View Cart – ניווט נכון וקריאה לפעולה", + "description": "בדיקת קישור View Cart בהודעת ההוספה לסל.", + "testId": "TC-F-025", + "testDescription": "כמשתמש, לאחר הוספת מוצר לסל אני רוצה לנחות בעמוד הסל בלחיצה על 'VIEW CART'.", + "prerequisites": "מוצר הוסף לסל מדף מוצר.", + "stepsToPerform": "1. לחץ 'VIEW CART' מההודעה הצפה.\n2. אמת הגעה לעמוד הסל.", + "expectedResult": "עמוד הסל נטען. קיים מסלול חזרה לקניות." + }, + { + "type": "functional", + "title": "בדיקת ריבוי שיטות משלוח ועדכון סכום", + "description": "חזרה ממוקדת על שלוש השיטות: Local pickup, Delivery Express, Registered Mail.", + "testId": "TC-F-026", + "testDescription": "כקונה, אני בוחר כל אחת משלוש שיטות המשלוח ומוודא שהטוטאל משתנה בהתאם, וההערה על זמן אספקה מוצגת.", + "prerequisites": "סל עם פריט אחד.", + "stepsToPerform": "1. בחר Local pickup – ודא משלוח ₪0.\n2. בחר Delivery Express – ודא תוספת ₪12.50 ותיאור '(1–3 days)'.\n3. בחר Registered Mail – ודא תוספת ₪5.90 ותיאור '(5–8 days)'.", + "expectedResult": "כל בחירה משנה מיידית את הסכום הכולל ומציגה תיאור זמן אספקה." + }, + { + "type": "functional", + "title": "השוואת הוספה לסל מול הסרה – סכום כולל חוזר לברירת מחדל", + "description": "בדיקת תקינות חישוב לאחר פעולות רצופות.", + "testId": "TC-F-027", + "testDescription": "כקונה, אני מוסיף ומסיר פריטים בזו אחר זו ומוודא שהסכומים תקינים ואין סכומים \"יתומים\" של משלוח ללא פריטים.", + "prerequisites": "סל ריק בהתחלה.", + "stepsToPerform": "1. הוסף 'Red Hoodie' → בחר Registered Mail.\n2. הסר את הפריט.\n3. אמת שהטוטאל=₪0 ושורה משלוח מוסרת.", + "expectedResult": "אין שאריות חישוב. הטוטאל מאופס בהסרת כל הפריטים." + }, + { + "type": "non-functional", + "title": "מניעת XSS/Injection בשדות הכתובת", + "description": "בדיקת סינון קלט והצגה בטוחה.", + "testId": "TC-NF-011", + "testDescription": "כאיש אבטחה, אני מזין קלט זדוני בשדות (לדוגמה ) ומוודא שהטקסט מסונן/מוטמע כטקסט ולא כקוד.", + "prerequisites": "דף קופה פתוח.", + "stepsToPerform": "1. הזן בשדה Company name: ''.\n2. שמור/שלם אם אפשר.\n3. בדוק את תצוגת התקציר/אימייל אישור (אם נשלח).", + "expectedResult": "אין הרצת סקריפט. התווים מוצגים כטקסט או מסוננים." + }, + { + "type": "non-functional", + "title": "מניעת דליפה של פרטי לקוח ל-Referrer", + "description": "בדיקת Referrer-Policy ו-GDPR/PPL התאמה.", + "testId": "TC-NF-012", + "testDescription": "כבודק פרטיות, אני מוודא ש-Referrer-Policy=Strict-Origin-When-Cross-Origin או דומה כדי שלא להעביר PII בעת יציאה לדומיין חיצוני (למשל ספק תשלום).", + "prerequisites": "כלי DevTools/HTTP Headers.", + "stepsToPerform": "1. פתח DevTools → Network.\n2. נווט לקישור חיצוני (אם קיים).\n3. בדוק Header 'Referer'.", + "expectedResult": "אין PII ב-Referer. המדיניות מחמירה." + }, + { + "type": "non-functional", + "title": "בדיקת יציבות כיווניות RTL/LTR במעבר בין שפות", + "description": "ודא ש-Layout לא נשבר בעת החלפת שפה.", + "testId": "TC-NF-013", + "testDescription": "כבודק i18n, אני בוחן אלמנטים כגון פאג'ינציה, סכומי כסף וחצים שנשמרים בכיוון הנכון בכל שינוי שפה.", + "prerequisites": "אתר עם מתג שפה.", + "stepsToPerform": "1. עבור לאנגלית ובדוק שהמטבע ₪ נשאר.\n2. חזור לעברית ובדוק שהפאג'ינציה מיושרת לימין.", + "expectedResult": "אין שבירת UI. המטבע נשאר ₪ בכל שפה." + } + ] +} \ No newline at end of file diff --git a/functional_tests/roost_test_1766048227/roost_test_1766048227.xlsx b/functional_tests/roost_test_1766048227/roost_test_1766048227.xlsx new file mode 100644 index 0000000..633e9f5 Binary files /dev/null and b/functional_tests/roost_test_1766048227/roost_test_1766048227.xlsx differ diff --git a/functional_tests/roost_test_1766048227/roost_test_1766048227.yaml b/functional_tests/roost_test_1766048227/roost_test_1766048227.yaml new file mode 100644 index 0000000..a1f9ea4 --- /dev/null +++ b/functional_tests/roost_test_1766048227/roost_test_1766048227.yaml @@ -0,0 +1,968 @@ +openapi: 3.0.3 +info: + title: API מסחר אלקטרוני – קטלוג, סל, קופונים, משלוח, קופה והזמנות + version: 1.0.0 + description: > + מפרט OpenAPI המבוסס על תרחישי Gherkin שסופקו. הממשק תומך בקטלוג, סל קניות, קופונים, + שיטות משלוח, קופה (Checkout) והזמנות, כולל ולידציות, שיטות תשלום, ומדדי מחיר + עם מטבע "₪" (ILS) ומע"מ ישראלי (17%) לפי הצורך. + + מאפיינים עיקריים: + - שימוש במזהה סשן אורח/משתמש דרך כותרת X-Session-Id עבור התמדה של סל. + - שימוש מומלץ בכותרת Idempotency-Key בבקשות POST קריטיות (Checkout/Orders) למניעת כפל הזמנות. + - תמיכה בכותרת Accept-Language (he-IL/en-US) לצרכי לוקליזציה הודעות. + - מיפוי שיטות משלוח: local_pickup (₪0), delivery_express (₪12.50), registered_mail (₪5.90). + - מיפוי שיטות תשלום: bank_transfer (Direct Bank Transfer), cod (Cash on Delivery). + +servers: + - url: '{API_BASE_URL}' + description: > + בסיס ה-API לפי משתנה הסביבה API_BASE_URL (כפי שמצויין ב-Background של התרחישים). + יש להגדיר כ-HTTPS בלבד. + variables: + API_BASE_URL: + default: https://staging.shop.example.com/api + description: > + כתובת בסיס לדוגמה. בסביבות ייצור/בדיקות יש להציב את ה-URL המתאים (למשל https://prod.shop.example.com/api). + +tags: + - name: Catalog + description: קטלוג מוצרים, עמודים, מיון ופירוט מוצר + - name: Cart + description: סל קניות – הוספה, עדכון, מחיקה, שיטות משלוח וסה"כ + - name: Coupons + description: החלת קופונים והסרתם + - name: Shipping + description: שיטות משלוח, עלויות וזמני אספקה + - name: Checkout + description: ולידציות קופה לפני הזמנה + - name: Orders + description: יצירת הזמנות ושליפתן + - name: Payments + description: שליפת אמצעי תשלום זמינים + - name: Reviews + description: ביקורות ודירוגים על מוצרים + - name: Health + description: בדיקת בריאות שירות + +paths: + /health: + get: + tags: [Health] + summary: בדיקת בריאות השירות + description: מחזיר סטטוס תקין לבדיקות ניטור. + responses: + '200': + description: תקין + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: ok + + /catalog/products: + get: + tags: [Catalog] + summary: שליפת מוצרים עם תמיכה בעמודים ומיון + description: > + שליפת רשימת מוצרים מהקטלוג. נתמך עימוד (page/page_size), סינון לפי קטגוריה, + ומיון כגון price_asc. + parameters: + - name: page + in: query + description: מספר עמוד (לדוגמה: 2 לתרחיש פאג'ינציה) + schema: { type: integer, minimum: 1, default: 1 } + - name: page_size + in: query + description: כמות תוצאות בעמוד + schema: { type: integer, minimum: 1, maximum: 100, default: 12 } + - name: category + in: query + description: סינון לפי קטגוריה (למשל "Men") + schema: { type: string } + - name: sort + in: query + description: מיון (price_asc, price_desc, newest, popular) + schema: + type: string + enum: [price_asc, price_desc, newest, popular] + - $ref: '#/components/parameters/AcceptLanguage' + responses: + '200': + description: רשימת מוצרים + content: + application/json: + schema: + $ref: '#/components/schemas/ProductList' + examples: + page2: + summary: עמוד 2 עם "Red Hoodie" + value: + page: 2 + page_size: 12 + total: 14 + results: + - id: 12345 + name: Red Hoodie + slug: red-hoodie + category_path: ["Home", "Men"] + price: + amount: 150.0 + currency: ILS + display: "₪150.00" + image_url: https://cdn.example.com/images/red-hoodie.jpg + stock_status: in_stock + + /catalog/products/{productId}: + get: + tags: [Catalog] + summary: פירוט מוצר לפי מזהה + description: מחזיר פרטי מוצר כולל מחיר במטבע ₪ ופירורי לחם. + parameters: + - name: productId + in: path + required: true + schema: { type: integer } + - $ref: '#/components/parameters/AcceptLanguage' + responses: + '200': + description: פרטי מוצר + content: + application/json: + schema: + $ref: '#/components/schemas/Product' + examples: + redHoodie: + value: + id: 12345 + name: Red Hoodie + slug: red-hoodie + category_path: ["Home", "Men", "Red Hoodie"] + price: + amount: 150.0 + currency: ILS + display: "₪150.00" + stock_status: in_stock + images: + - https://cdn.example.com/images/red-hoodie.jpg + + /cart: + get: + tags: [Cart] + summary: שליפת סל לפי סשן + description: > + מחזיר את הסל הנוכחי עבור X-Session-Id, כולל פריטים, שיטת משלוח, סיכומים, מטבע ₪ ומע"מ. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - $ref: '#/components/parameters/AcceptLanguage' + responses: + '200': + description: סל קיים + content: + application/json: + schema: + $ref: '#/components/schemas/Cart' + examples: + withItem: + value: + items: + - item_id: "itm_001" + product_id: 12345 + name: Red Hoodie + quantity: 1 + unit_price: { amount: 150.0, currency: ILS, display: "₪150.00" } + line_total: { amount: 150.0, currency: ILS, display: "₪150.00" } + image_url: https://cdn.example.com/images/red-hoodie.jpg + stock_status: in_stock + shipping_method: local_pickup + shipping_cost: { amount: 0.0, currency: ILS, display: "₪0" } + subtotal: { amount: 150.0, currency: ILS, display: "₪150.00" } + discount: { amount: 0.0, currency: ILS, display: "₪0" } + tax_lines: + - name: "VAT" + rate: 0.17 + amount: { amount: 21.79, currency: ILS, display: "₪21.79" } + total: { amount: 171.79, currency: ILS, display: "₪171.79" } + currency: ILS + '404': + description: סל לא נמצא (סשן לא קיים) + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + delete: + tags: [Cart] + summary: ניקוי סל + description: מחיקת כל הפריטים והקופונים מהסל עבור הסשן. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + responses: + '204': + description: הסל נוקה + '404': + description: סל לא נמצא + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + /cart/items: + post: + tags: [Cart] + summary: הוספת פריט לסל + description: > + הוספת מוצר לסל לפי product_id וכמות. במקרה של חוסר מלאי תוחזר שגיאה מתאימה. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - $ref: '#/components/parameters/AcceptLanguage' + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [product_id, quantity] + properties: + product_id: + type: integer + example: 12345 + quantity: + type: integer + minimum: 1 + example: 1 + responses: + '201': + description: נוסף פריט והסל המעודכן מוחזר + content: + application/json: + schema: + $ref: '#/components/schemas/Cart' + '409': + description: אזל מהמלאי + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + examples: + oos: + value: + code: out_of_stock + message: "אזל מהמלאי" + '400': + description: בקשה לא חוקית + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + /cart/items/{itemId}: + put: + tags: [Cart] + summary: עדכון כמות של פריט בסל + description: שינוי כמות והחזרת סל מעודכן כולל חישובי משלוח/מס. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - name: itemId + in: path + required: true + schema: { type: string } + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [quantity] + properties: + quantity: + type: integer + minimum: 0 + description: אם 0 – הפריט יוסר מהסל + example: 2 + responses: + '200': + description: סל מעודכן + content: + application/json: + schema: { $ref: '#/components/schemas/Cart' } + '404': + description: פריט לא נמצא בסל + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + delete: + tags: [Cart] + summary: הסרת פריט מהסל + description: > + הסרת פריט בודד והחזרת הודעת עדכון. אם הסל ריק – total יהיה "₪0". + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - name: itemId + in: path + required: true + schema: { type: string } + responses: + '200': + description: פריט הוסר והסל עודכן + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: Cart updated + cart: + $ref: '#/components/schemas/Cart' + '404': + description: פריט לא נמצא בסל + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + /cart/shipping: + get: + tags: [Shipping, Cart] + summary: שליפת שיטות משלוח זמינות לסל + description: > + מחזיר את שיטות המשלוח הזמינות לסל הנוכחי כולל עלות זמן אספקה. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + responses: + '200': + description: רשימת שיטות משלוח + content: + application/json: + schema: + type: object + properties: + methods: + type: array + items: { $ref: '#/components/schemas/ShippingMethod' } + examples: + methods: + value: + methods: + - code: local_pickup + label: "Local pickup" + cost: { amount: 0.0, currency: ILS, display: "₪0" } + eta: "" + - code: delivery_express + label: "Delivery Express" + cost: { amount: 12.5, currency: ILS, display: "₪12.50" } + eta: "(1–3 days)" + - code: registered_mail + label: "Registered Mail" + cost: { amount: 5.9, currency: ILS, display: "₪5.90" } + + put: + tags: [Shipping, Cart] + summary: עדכון שיטת משלוח בסל + description: > + עדכון שיטת המשלוח (local_pickup, delivery_express, registered_mail) והחזרת הסל המעודכן. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [method] + properties: + method: + type: string + enum: [local_pickup, delivery_express, registered_mail] + example: registered_mail + responses: + '200': + description: סל מעודכן עם שיטת משלוח חדשה + content: + application/json: + schema: { $ref: '#/components/schemas/Cart' } + examples: + registered: + value: + shipping_method: registered_mail + shipping_cost: { amount: 5.9, currency: ILS, display: "₪5.90" } + # שדות סל נוספים יוחזרו בהתאם + '400': + description: שיטת משלוח לא חוקית + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + /coupons/apply: + post: + tags: [Coupons] + summary: החלת קופון על הסל + description: > + החלת קופון לפי קוד. הצלחה – מוחזר discount_amount וסל מעודכן. כשל – 400 עם שדה error. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - $ref: '#/components/parameters/AcceptLanguage' + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [code] + properties: + code: + type: string + example: SALE10 + responses: + '200': + description: קופון הוחל בהצלחה + content: + application/json: + schema: + $ref: '#/components/schemas/CouponApplyResponse' + examples: + success: + value: + code: "SALE10" + message: "Coupon applied" + discount_amount: { amount: 15.0, currency: ILS, display: "₪15.00" } + cart: + discount: { amount: 15.0, currency: ILS, display: "₪15.00" } + total: { amount: 156.79, currency: ILS, display: "₪156.79" } + '400': + description: קופון לא תקף + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: "קופון לא תקף" + + /coupons/{code}: + delete: + tags: [Coupons] + summary: הסרת קופון מהסל + description: מסיר קופון פעיל ומחזיר סל מעודכן. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - name: code + in: path + required: true + schema: { type: string } + responses: + '200': + description: קופון הוסר + content: + application/json: + schema: + type: object + properties: + message: { type: string, example: "Coupon removed" } + cart: { $ref: '#/components/schemas/Cart' } + + /payment/methods: + get: + tags: [Payments] + summary: שליפת שיטות תשלום זמינות + description: > + מחזיר רשימת שיטות תשלום זמינות בהתבסס על המדינה/שילוח/סכום בסל. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + responses: + '200': + description: רשימת שיטות תשלום + content: + application/json: + schema: + type: object + properties: + methods: + type: array + items: { $ref: '#/components/schemas/PaymentMethod' } + examples: + default: + value: + methods: + - code: bank_transfer + title: "Direct Bank Transfer" + - code: cod + title: "Cash on Delivery" + + /checkout: + post: + tags: [Checkout] + summary: ולידציות קופה לפני יצירת הזמנה + description: > + מבצע בדיקות ולידציה עבור פרטי חיוב/משלוח/תשלום לפני יצירת הזמנה. + שימוש מומלץ ב-Idempotency-Key כדי להימנע מלחיצות כפולות. + במקרה של שגיאות ולידציה – יוחזר 400 עם הודעה קריאה. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - $ref: '#/components/parameters/IdempotencyKeyHeader' + - $ref: '#/components/parameters/AcceptLanguage' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutRequest' + examples: + missingPostcode: + summary: חסר מיקוד + value: + billing: + first_name: "Meital" + last_name: "Kenzi" + company: "Menora" + country: "IL" + address_1: "Burla yehuda 1" + address_2: "17" + city: "Tel Aviv" + postcode: null + phone: "0544344345" + email: "meitalkenzi@gmail.com" + shipping_method: "registered_mail" + payment_method: "bank_transfer" + invalidPayment: + summary: אמצעי תשלום לא תקין + value: + billing: + first_name: "Meital" + last_name: "Kenzi" + company: "Menora" + country: "IL" + address_1: "Burla yehuda 1" + address_2: "17" + city: "Tel Aviv" + postcode: "316547" + phone: "0544344345" + email: "meitalkenzi@gmail.com" + shipping_method: "registered_mail" + payment_method: "invalid" + responses: + '200': + description: ולידציה עברה בהצלחה, ניתן להמשיך ליצירת הזמנה + content: + application/json: + schema: + type: object + properties: + valid: { type: boolean, example: true } + next_step: { type: string, example: "place_order" } + '400': + description: שגיאת ולידציה + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + examples: + missingPostcode: + value: + code: validation_error + message: "Billing Postcode / ZIP is a required field." + field_errors: + postcode: "required" + invalidPayment: + value: + code: validation_error + message: "Invalid payment method" + + /orders: + post: + tags: [Orders] + summary: יצירת הזמנה + description: > + יוצר הזמנה מסל קיים ושיטת משלוח נבחרת. דורש פרטי חיוב ואמצעי תשלום תקף. + מומלץ לספק Idempotency-Key כדי למנוע הזמנות כפולות בלחיצה כפולה. + parameters: + - $ref: '#/components/parameters/XSessionIdHeader' + - $ref: '#/components/parameters/IdempotencyKeyHeader' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OrderCreateRequest' + examples: + successBankTransfer: + value: + billing: + first_name: "Dana" + last_name: "Cohen" + country: "IL" + address_1: "Yehuda Halevi 10" + city: "Tel Aviv" + postcode: "6473421" + phone: "0521234567" + email: "dana@example.com" + payment_method: "bank_transfer" + confirm: true + responses: + '201': + description: הזמנה נוצרה בהצלחה + headers: + Idempotency-Key: + description: מוחזר כפי שנשלח, לאיתור כפילויות + schema: { type: string } + content: + application/json: + schema: { $ref: '#/components/schemas/Order' } + examples: + created: + value: + order_id: "ord_10001" + status: "processing" + totals: + subtotal: { amount: 150.0, currency: ILS, display: "₪150.00" } + shipping: { amount: 0.0, currency: ILS, display: "₪0" } + discount: { amount: 0.0, currency: ILS, display: "₪0" } + tax: { amount: 21.79, currency: ILS, display: "₪21.79" } + total: { amount: 171.79, currency: ILS, display: "₪171.79" } + created_at: "2025-01-01T10:15:00Z" + payment: + method: bank_transfer + title: "Direct Bank Transfer" + '400': + description: שגיאת ולידציה/תשלום + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + examples: + invalidPayment: + value: + code: validation_error + message: "Invalid payment method" + '409': + description: בקשה כפולה זוהתה לפי Idempotency-Key – לא נוצרת הזמנה נוספת + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + examples: + duplicate: + value: + code: duplicate_request + message: "Order already created for this Idempotency-Key" + details: + existing_order_id: "ord_10001" + + /orders/{orderId}: + get: + tags: [Orders] + summary: שליפת פרטי הזמנה + description: מחזיר פרטי הזמנה לפי מזהה. + parameters: + - name: orderId + in: path + required: true + schema: { type: string } + responses: + '200': + description: פרטי הזמנה + content: + application/json: + schema: { $ref: '#/components/schemas/Order' } + '404': + description: הזמנה לא נמצאה + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + + /products/{productId}/reviews: + get: + tags: [Reviews] + summary: שליפת ביקורות למוצר + description: > + מחזיר רשימת ביקורות כולל דירוג ממוצע. נתמך עימוד. + parameters: + - name: productId + in: path + required: true + schema: { type: integer } + - name: page + in: query + schema: { type: integer, default: 1 } + responses: + '200': + description: רשימת ביקורות + content: + application/json: + schema: + type: object + properties: + total: { type: integer } + page: { type: integer } + reviews: + type: array + items: + type: object + properties: + rating: { type: integer, minimum: 1, maximum: 5 } + author: { type: string } + content: { type: string } + created_at: { type: string, format: date-time } + post: + tags: [Reviews] + summary: הוספת ביקורת על מוצר + description: > + הוספת ביקורת ודירוג. אם דורש התחברות – תוחזר שגיאת 401 עם הודעה מתאימה. + parameters: + - name: productId + in: path + required: true + schema: { type: integer } + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [rating, content] + properties: + rating: { type: integer, minimum: 1, maximum: 5, example: 4 } + content: { type: string, example: "מוצר מעולה!" } + guest_email: { type: string, format: email, description: נדרש אם מתאפשר לאורחים } + responses: + '201': + description: ביקורת נשמרה + content: + application/json: + schema: + type: object + properties: + review_id: { type: string } + status: { type: string, example: "approved" } + '401': + description: נדרש להתחבר כדי לדרג + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + examples: + mustLogin: + value: + code: auth_required + message: "יש להתחבר כדי לדרג" + +components: + securitySchemes: + SessionId: + type: apiKey + in: header + name: X-Session-Id + description: מזהה סשן אורח/משתמש לשימור סל ופעולות קשורות + IdempotencyKey: + type: apiKey + in: header + name: Idempotency-Key + description: מפתח אידמפוטנטיות למניעת כפילויות ביצירת הזמנה/קופה + parameters: + XSessionIdHeader: + name: X-Session-Id + in: header + required: true + schema: + type: string + description: מזהה סשן לשיוך הסל (נוצר בצד הלקוח או בשרת) + AcceptLanguage: + name: Accept-Language + in: header + required: false + schema: + type: string + example: he-IL + description: העדפת שפה לתגובות (he-IL/en-US) + IdempotencyKeyHeader: + name: Idempotency-Key + in: header + required: false + schema: + type: string + example: 3d9c3f5b-6c7e-4a1b-a5a4-8b2f0e2b2c1a + description: מומלץ בבקשות POST קריטיות למניעת הזמנות כפולות + schemas: + Money: + type: object + properties: + amount: { type: number, format: float, example: 12.5 } + currency: + type: string + enum: [ILS] + example: ILS + display: + type: string + example: "₪12.50" + ShippingMethod: + type: object + properties: + code: + type: string + enum: [local_pickup, delivery_express, registered_mail] + label: + type: string + example: "Delivery Express" + cost: + $ref: '#/components/schemas/Money' + eta: + type: string + example: "(1–3 days)" + CartItem: + type: object + properties: + item_id: { type: string } + product_id: { type: integer } + name: { type: string } + quantity: { type: integer, minimum: 0 } + unit_price: { $ref: '#/components/schemas/Money' } + line_total: { $ref: '#/components/schemas/Money' } + image_url: { type: string, format: uri } + stock_status: + type: string + enum: [in_stock, out_of_stock] + Cart: + type: object + properties: + items: + type: array + items: { $ref: '#/components/schemas/CartItem' } + shipping_method: + type: string + enum: [local_pickup, delivery_express, registered_mail, null] + nullable: true + shipping_cost: { $ref: '#/components/schemas/Money' } + subtotal: { $ref: '#/components/schemas/Money' } + discount: { $ref: '#/components/schemas/Money' } + tax_lines: + type: array + items: + type: object + properties: + name: { type: string, example: "VAT" } + rate: { type: number, example: 0.17 } + amount: { $ref: '#/components/schemas/Money' } + total: { $ref: '#/components/schemas/Money' } + currency: + type: string + enum: [ILS] + coupon_lines: + type: array + items: + type: object + properties: + code: { type: string, example: "SALE10" } + amount: { $ref: '#/components/schemas/Money' } + CouponApplyResponse: + type: object + properties: + code: { type: string } + message: { type: string } + discount_amount: { $ref: '#/components/schemas/Money' } + cart: { $ref: '#/components/schemas/Cart' } + BillingAddress: + type: object + required: [first_name, last_name, country, address_1, city, postcode, phone, email] + properties: + first_name: { type: string } + last_name: { type: string } + company: { type: string, nullable: true } + country: { type: string, example: "IL" } + address_1: { type: string } + address_2: { type: string, nullable: true } + city: { type: string } + postcode: { type: string, nullable: true } + phone: { type: string } + email: { type: string, format: email } + CheckoutRequest: + type: object + required: [billing, shipping_method, payment_method] + properties: + billing: { $ref: '#/components/schemas/BillingAddress' } + shipping_method: + type: string + enum: [local_pickup, delivery_express, registered_mail] + payment_method: + type: string + description: > + קוד אמצעי תשלום (bank_transfer, cod). ערכים אחרים ייחשבו כלא תקפים. + example: bank_transfer + OrderCreateRequest: + type: object + required: [billing, payment_method, confirm] + properties: + billing: { $ref: '#/components/schemas/BillingAddress' } + payment_method: + type: string + enum: [bank_transfer, cod] + confirm: + type: boolean + description: אישור סופי ליצירת הזמנה + example: true + Order: + type: object + properties: + order_id: { type: string, example: "ord_10001" } + status: + type: string + enum: [pending, processing, completed, failed, cancelled] + example: processing + totals: + type: object + properties: + subtotal: { $ref: '#/components/schemas/Money' } + shipping: { $ref: '#/components/schemas/Money' } + discount: { $ref: '#/components/schemas/Money' } + tax: { $ref: '#/components/schemas/Money' } + total: { $ref: '#/components/schemas/Money' } + created_at: { type: string, format: date-time } + payment: + type: object + properties: + method: { type: string, example: bank_transfer } + title: { type: string, example: "Direct Bank Transfer" } + PaymentMethod: + type: object + properties: + code: + type: string + enum: [bank_transfer, cod] + title: + type: string + example: "Cash on Delivery" + Product: + type: object + properties: + id: { type: integer } + name: { type: string } + slug: { type: string } + category_path: + type: array + items: { type: string } + price: { $ref: '#/components/schemas/Money' } + stock_status: + type: string + enum: [in_stock, out_of_stock] + images: + type: array + items: { type: string, format: uri } + ProductList: + type: object + properties: + page: { type: integer } + page_size: { type: integer } + total: { type: integer } + results: + type: array + items: { $ref: '#/components/schemas/Product' } + ErrorResponse: + type: object + properties: + code: { type: string, example: validation_error } + message: { type: string, example: "Invalid payment method" } + field_errors: + type: object + additionalProperties: { type: string } + details: + type: object + additionalProperties: true + +security: + - SessionId: []