From 21ed3dc9241bca7b7787b3de511c7bfa3c346df0 Mon Sep 17 00:00:00 2001 From: zackdotcat Date: Thu, 9 Jan 2025 17:49:02 -0500 Subject: [PATCH] WIP --- beta-case-studies/hardware_store/README.md | 79 ++++++++ .../hardware_store/generate_data.py | 104 ++++++++++ .../hardware_store/generated_data.sql | 182 ++++++++++++++++++ .../hardware_store/requirements.txt | 2 + beta-case-studies/hardware_store/schema.sql | 61 ++++++ beta-case-studies/museum_exhibits/README.md | 72 +++++++ .../museum_exhibits/generate_data.py | 103 ++++++++++ .../museum_exhibits/generated_data.sql | 102 ++++++++++ .../museum_exhibits/requirements.txt | 2 + beta-case-studies/museum_exhibits/schema.sql | 42 ++++ .../screenshot-generation/Dockerfile | 13 ++ .../screenshot-generation/entrypoint.sh | 10 + .../screenshot-generation/justfile | 3 + .../screenshot-generation/package-lock.json | 71 +++++++ .../screenshot-generation/package.json | 5 + .../playwright.config.ts | 11 ++ .../screenshot-generation/tests/init.spec.ts | 12 ++ .../tests/test-1.spec.ts | 69 +++++++ 18 files changed, 943 insertions(+) create mode 100644 beta-case-studies/hardware_store/README.md create mode 100644 beta-case-studies/hardware_store/generate_data.py create mode 100644 beta-case-studies/hardware_store/generated_data.sql create mode 100644 beta-case-studies/hardware_store/requirements.txt create mode 100644 beta-case-studies/hardware_store/schema.sql create mode 100644 beta-case-studies/museum_exhibits/README.md create mode 100644 beta-case-studies/museum_exhibits/generate_data.py create mode 100644 beta-case-studies/museum_exhibits/generated_data.sql create mode 100644 beta-case-studies/museum_exhibits/requirements.txt create mode 100644 beta-case-studies/museum_exhibits/schema.sql create mode 100644 beta-case-studies/screenshot-generation/Dockerfile create mode 100644 beta-case-studies/screenshot-generation/entrypoint.sh create mode 100644 beta-case-studies/screenshot-generation/justfile create mode 100644 beta-case-studies/screenshot-generation/package-lock.json create mode 100644 beta-case-studies/screenshot-generation/package.json create mode 100644 beta-case-studies/screenshot-generation/playwright.config.ts create mode 100644 beta-case-studies/screenshot-generation/tests/init.spec.ts create mode 100644 beta-case-studies/screenshot-generation/tests/test-1.spec.ts diff --git a/beta-case-studies/hardware_store/README.md b/beta-case-studies/hardware_store/README.md new file mode 100644 index 0000000..497fdb1 --- /dev/null +++ b/beta-case-studies/hardware_store/README.md @@ -0,0 +1,79 @@ +# Hardware Store sample data + +This sample dataset represents a chain of hardware stores managing their inventory and rentals. + +```mermaid +%% https://mermaid.js.org/syntax/entityRelationshipDiagram.html + +erDiagram + "Store Locations" { + BIGINT id PK + string name + string address + } + + "Customers" { + BIGINT id PK + string first_name + string last_name + string email + string phone + string address + } + + "Assets" { + BIGINT id PK + string name + string serial_number + NUMERIC rental_price + NUMERIC sale_price + string rental_period + string location + BIGINT store_id FK + } + + "Transactions" { + BIGINT id PK + BIGINT asset_id FK + BIGINT customer_id FK + string transaction_type + TIMESTAMP transaction_date + NUMERIC total_charge + string note + } + + "Rentals" { + BIGINT id PK + BIGINT transaction_id FK + TIMESTAMP rental_start + TIMESTAMP rental_end + TIMESTAMP time_out + TIMESTAMP time_in + INTERVAL rental_time + } + +%% Relationships +%% See: https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax + "Assets" ||--|{ "Store Locations" : "store_id" + "Transactions" ||--|| "Assets" : "asset_id" + "Transactions" ||--|{ "Customers" : "customer_id" + "Rentals" ||--|| "Transactions" : "transaction_id" +``` + + +## Loading Data + +The generated SQL file, `generate_data/load_data.sql`, contains all the necessary COPY commands to import data into your database. The data (and the load data file) are produced by the `generate_data.py` file, which can be adjusted and re-run to alter the data if needed. + +Load the data into a locally-running Mathesar instance like this: + +```shell +# First load the schema and tables +docker exec -i mathesar_dev_db bash -c 'psql -U mathesar' < schema.sql +# Then the sample data +docker exec -i mathesar_dev_db bash -c 'psql -U mathesar' < generated_data.sql +``` + +## Development + +The only requirement is to install dependencies with `pip install -r requirements.txt`. diff --git a/beta-case-studies/hardware_store/generate_data.py b/beta-case-studies/hardware_store/generate_data.py new file mode 100644 index 0000000..2a9f6c3 --- /dev/null +++ b/beta-case-studies/hardware_store/generate_data.py @@ -0,0 +1,104 @@ +import os +import random +from faker import Faker +import faker_commerce + +fake = Faker() +fake.add_provider(faker_commerce.Provider) + +# Number of rows to generate +NUM_STORES = 5 +NUM_CUSTOMERS = 20 +NUM_ASSETS = 50 +NUM_TRANSACTIONS = 60 +NUM_RENTALS = 30 + +# Helper function to clean values for COPY +def clean_value(value): + if value is None: + return r"\N" + if isinstance(value, str): + return value.replace("\t", " ").replace("\n", " ") + return str(value) + +# Table Data Generation +def generate_store_locations(): + for i in range(1, NUM_STORES + 1): + yield [i, fake.company(), fake.address()] + +def generate_customers(): + for i in range(1, NUM_CUSTOMERS + 1): + yield [ + i, + fake.first_name(), + fake.last_name(), + fake.email(), + fake.phone_number(), + fake.address(), + ] + +def generate_assets(store_ids): + for i in range(1, NUM_ASSETS + 1): + rental_period = random.choice(["daily", "weekly", "monthly"]) + rental_price = round(random.uniform(5, 100), 2) + sale_price = ( + round(rental_price * random.uniform(0.5, 0.8), 2) # Discounted sale price + if random.random() < 0.2 else None + ) + yield [ + i, + fake.ecommerce_name(), + fake.unique.ean13(), + rental_price, + sale_price, + rental_period, + f"Aisle {random.randint(1, 20)} - Shelf {random.randint(1, 10)}", + random.choice(store_ids), + ] + +def generate_transactions(asset_ids, customer_ids): + for i in range(1, NUM_TRANSACTIONS + 1): + asset_id = random.choice(asset_ids) + customer_id = random.choice(customer_ids) + transaction_type = random.choice(["Sale", "Rental", "Return"]) + transaction_date = fake.date_time_this_year() + total_charge = round(random.uniform(10, 500), 2) + yield [i, asset_id, customer_id, transaction_type, transaction_date, total_charge, fake.sentence()] + +def generate_rentals(transaction_ids): + for i in range(1, NUM_RENTALS + 1): + transaction_id = random.choice(transaction_ids) + rental_start = fake.date_time_this_year() + rental_end = fake.date_time_between_dates(datetime_start=rental_start) + rental_time = rental_end - rental_start + yield [i, transaction_id, rental_start, rental_end, rental_start, rental_end, rental_time] + +# Generate Data +store_ids = list(range(1, NUM_STORES + 1)) +customer_ids = list(range(1, NUM_CUSTOMERS + 1)) +asset_ids = list(range(1, NUM_ASSETS + 1)) +transaction_ids = list(range(1, NUM_TRANSACTIONS + 1)) + +tables = { + "Store Locations": generate_store_locations(), + "Customers": generate_customers(), + "Assets": generate_assets(store_ids), + "Transactions": generate_transactions(asset_ids, customer_ids), + "Rentals": generate_rentals(transaction_ids), +} + +# Write to SQL file +sql_file = os.path.join(os.getcwd(), "generated_data.sql") + +with open(sql_file, "w") as f: + f.write('SET search_path="Hardware Store";\n\n') + + for table_name, generator in tables.items(): + # Add quotes around table name since it contains spaces + f.write(f'COPY "{table_name}" FROM stdin;\n') + for row in generator: + cleaned_row = "\t".join(map(clean_value, row)) + f.write(f"{cleaned_row}\n") + f.write("\\.\n\n") + +print(f"SQL file generated: {sql_file}") diff --git a/beta-case-studies/hardware_store/generated_data.sql b/beta-case-studies/hardware_store/generated_data.sql new file mode 100644 index 0000000..189da97 --- /dev/null +++ b/beta-case-studies/hardware_store/generated_data.sql @@ -0,0 +1,182 @@ +SET search_path="Hardware Store"; + +COPY "Store Locations" FROM stdin; +1 Martinez Ltd 351 Walker Field North Chris, MS 43962 +2 Morales, Warren and Powers 59649 Owens Burg Suite 809 East Debrafort, VA 35598 +3 Smith, Williams and King 121 Jason Route New Amberberg, MD 81135 +4 Mcgrath PLC 4684 Villarreal Dam Courtneyland, AS 80841 +5 Carson, Huang and Glass 4667 Parker Union Suite 197 Lake Karaborough, WY 98063 +\. + +COPY "Customers" FROM stdin; +1 Nathan Sandoval jeffreyguzman@example.com +1-834-253-2718x78673 PSC 9403, Box 0923 APO AA 51937 +2 Michelle Frederick rjames@example.com 940.581.3771x23049 0230 Mooney Run Suite 648 South Bridgetmouth, NM 38619 +3 Jason Wolf michealjones@example.org 264-853-2532x055 382 Heather Port Apt. 154 Edwardfort, ND 23251 +4 Matthew Santos david90@example.org (280)309-1124x69857 2984 Lambert Squares Suite 920 New Nicolemouth, FL 04497 +5 Joshua Wells petersjeffery@example.com 001-241-478-4184x30901 601 Melissa Way Port Brittanyfort, FL 55961 +6 Joan Hawkins peter23@example.com 4672048658 63424 Tyrone Cliff North Joshua, CO 08437 +7 Timothy Salazar anthony47@example.com (817)799-3712x4077 PSC 2346, Box 6451 APO AP 92230 +8 John Humphrey timothy30@example.net +1-658-617-5570x59293 29798 Andrew Centers Apt. 513 Lake John, MA 02980 +9 Dominique Meyer christina88@example.org 923.740.8343x728 USCGC Jackson FPO AP 24258 +10 Monica Gonzales josephtran@example.org 660-962-4435x0989 1368 Garza Wall Suite 337 East Scottfurt, IL 17866 +11 Michelle King ericramirez@example.net 669-220-5302 78586 Michelle Circle Apt. 098 New Melissachester, ID 18010 +12 James Williams adamsjohn@example.net +1-359-675-3266x4713 785 Peter River West Dwayneville, MA 24439 +13 Anthony Robinson jacksonpatrick@example.net 001-539-995-5047x36208 3064 Burns Fields Suite 900 Martintown, IA 49678 +14 Joseph Wise matabrent@example.com +1-219-313-7158x1139 9727 Dunlap Ridge North Jamesview, PA 57903 +15 Sharon Stokes craig97@example.org 339-982-9323x2512 414 Norman Cliff East Cynthia, MI 40779 +16 Sheila Moore johnsonmonica@example.org 399-206-9167x322 0062 Ashley Walk Suite 579 Dianeville, IN 89682 +17 David Gutierrez jeffrey91@example.net 543-294-5385x5325 971 Adam Village Thomaschester, IN 44216 +18 Michael Rodriguez brett57@example.com +1-898-870-7477x5103 0392 Hernandez Creek East Alexisborough, AZ 04523 +19 Matthew Hartman dicksonrichard@example.com +1-266-516-4327x3695 1855 Wiggins Drives Apt. 937 South Josemouth, MP 46006 +20 Jason Dickson flowerscrystal@example.com +1-662-269-3194x8923 328 Carr Groves Suite 783 West Joannehaven, MD 89851 +\. + +COPY "Assets" FROM stdin; +1 Gloves 6346253295973 47.7 \N weekly Aisle 8 - Shelf 5 3 +2 Practical Rubber Ball 0360005600613 50.84 \N weekly Aisle 7 - Shelf 3 5 +3 Mouse 8049248877557 60.57 \N daily Aisle 3 - Shelf 4 3 +4 Bike 7591778415989 20.11 \N weekly Aisle 12 - Shelf 7 3 +5 For repair Metal Bike 7365708441177 43.87 24.55 monthly Aisle 6 - Shelf 1 3 +6 Sleek Pants 4101833392143 30.47 \N weekly Aisle 1 - Shelf 6 1 +7 Refined Bike 3154904290740 32.57 \N daily Aisle 7 - Shelf 9 3 +8 Salad 9198069318462 42.29 \N monthly Aisle 12 - Shelf 8 2 +9 Fresh Bacon 5366484678834 28.14 \N monthly Aisle 17 - Shelf 10 5 +10 Metal Bike 2088599455157 40.94 \N weekly Aisle 7 - Shelf 10 5 +11 Tuna 9491110752124 96.82 \N daily Aisle 1 - Shelf 8 2 +12 Frozen Soap 0611585483210 20.23 10.63 monthly Aisle 17 - Shelf 6 3 +13 New Metal Computer 4830015470538 95.29 \N weekly Aisle 19 - Shelf 1 2 +14 Fantastic Fresh Car 8364376527229 97.97 \N daily Aisle 8 - Shelf 4 3 +15 Incredible Fish 2973304695891 69.37 46.09 daily Aisle 11 - Shelf 6 1 +16 Table 2051582634631 28.69 17.97 monthly Aisle 13 - Shelf 9 5 +17 Used Soft Shoes 5384203806542 93.75 \N monthly Aisle 19 - Shelf 4 1 +18 Ergonomic Bacon 3630539075919 47.22 28.35 daily Aisle 7 - Shelf 5 3 +19 Practical Rubber Shirt 4795855052521 77.77 \N daily Aisle 18 - Shelf 6 3 +20 Refined Wooden Towels 8649933817792 49.53 36.13 daily Aisle 15 - Shelf 2 3 +21 Handcrafted Cotton Cheese 1209585075994 90.74 61.55 monthly Aisle 17 - Shelf 3 4 +22 Car 8352981239767 49.83 \N daily Aisle 11 - Shelf 7 4 +23 Wooden Ball 2266622928254 65.49 33.13 monthly Aisle 10 - Shelf 7 2 +24 Bacon 4934936243308 12.76 \N monthly Aisle 12 - Shelf 7 4 +25 Steel Bacon 9965885729112 53.58 \N weekly Aisle 10 - Shelf 4 5 +26 New Towels 4432468396818 28.4 \N daily Aisle 4 - Shelf 3 2 +27 Rustic Plastic Shirt 3081422770006 43.44 \N monthly Aisle 1 - Shelf 7 1 +28 Intelligent Cheese 1517839480143 85.58 60.29 weekly Aisle 7 - Shelf 10 4 +29 Shoes 3496762612396 88.3 \N monthly Aisle 11 - Shelf 2 4 +30 Gorgeous Steel Chicken 4303432484544 46.06 \N weekly Aisle 11 - Shelf 8 1 +31 Steel Chair 5732168175478 89.69 \N weekly Aisle 6 - Shelf 3 3 +32 Tasty Granite Cheese 5567616046846 11.65 \N daily Aisle 9 - Shelf 6 5 +33 Sausages 0387889381087 71.59 \N daily Aisle 3 - Shelf 5 1 +34 Ergonomic Rubber Bike 9191608956538 22.38 \N daily Aisle 6 - Shelf 8 5 +35 Concrete Shoes 0444645343373 38.18 25.48 daily Aisle 20 - Shelf 9 4 +36 Gorgeous Rubber Pants 4524470397003 82.83 \N daily Aisle 10 - Shelf 2 2 +37 Metal Soap 2366615469778 54.33 33.77 daily Aisle 3 - Shelf 1 4 +38 Shoes 2591296431145 41.33 \N monthly Aisle 6 - Shelf 6 2 +39 Salad 4072225607636 99.69 \N monthly Aisle 8 - Shelf 1 1 +40 Shirt 1100435245379 50.15 \N monthly Aisle 9 - Shelf 5 2 +41 Small Chicken 7916950242465 41.81 \N daily Aisle 9 - Shelf 10 2 +42 Handcrafted Cotton Bike 1297557024521 44.46 \N weekly Aisle 12 - Shelf 6 1 +43 Tasty Metal Car 3767368920261 86.4 \N daily Aisle 20 - Shelf 7 4 +44 Frozen Computer 2123842533968 84.21 \N daily Aisle 14 - Shelf 1 1 +45 Granite Table 6335792223448 94.38 \N weekly Aisle 3 - Shelf 4 2 +46 Steel Soap 1446340431156 77.29 61.55 weekly Aisle 11 - Shelf 3 4 +47 Steel Car 6902849930798 99.42 \N monthly Aisle 16 - Shelf 7 2 +48 Fresh Towels 1407985277738 15.21 \N weekly Aisle 14 - Shelf 4 5 +49 Awesome Wooden Tuna 9773452228599 8.94 \N weekly Aisle 16 - Shelf 1 4 +50 Incredible Cotton Chair 3917327262066 48.25 \N weekly Aisle 19 - Shelf 4 2 +\. + +COPY "Transactions" FROM stdin; +1 39 14 Rental 2025-01-05 07:01:41.127635 33.89 Parent do next nothing. +2 34 12 Return 2025-01-06 00:36:46.357093 90.28 Middle lot indicate each own. +3 32 12 Rental 2025-01-08 22:11:39.650891 366.16 Certainly continue test staff instead. +4 9 1 Sale 2025-01-08 06:12:51.249842 231.8 Become deal above worker. +5 40 4 Return 2025-01-02 21:04:51.663746 86.12 Their authority truth. +6 43 17 Return 2025-01-07 03:18:19.432767 351.85 Nearly kind watch government. +7 30 18 Rental 2025-01-05 23:48:44.215668 114.87 Opportunity agency item shake garden. +8 18 13 Return 2025-01-07 23:16:50.086201 263.57 After not focus evening issue sort. +9 9 5 Return 2025-01-06 01:56:13.507773 484.27 By since from impact network rich. +10 2 14 Return 2025-01-05 12:11:32.712421 333.68 Enjoy best worker trouble generation sense conference. +11 42 11 Sale 2025-01-08 10:27:41.449848 288.18 Source establish rock. +12 21 1 Sale 2025-01-04 00:19:36.450256 426.97 Me early pretty interesting series for. +13 18 12 Return 2025-01-04 08:27:53.644542 447.06 Put memory state purpose activity out. +14 18 1 Rental 2025-01-07 04:04:34.414619 193.66 Learn surface avoid third month guy western. +15 38 15 Return 2025-01-03 03:01:31.908378 401.74 Anything eye assume one close. +16 42 8 Rental 2025-01-01 20:00:04.582708 135.68 Across success our. +17 7 10 Rental 2025-01-01 10:32:23.010572 388.96 Easy our garden challenge attorney true. +18 39 16 Return 2025-01-07 22:53:59.558770 440.86 Day nation entire opportunity specific. +19 44 3 Sale 2025-01-07 20:04:35.403750 68.49 True different miss represent treat style life total. +20 35 9 Rental 2025-01-03 22:09:19.439293 241.85 Nature art morning animal reality consider. +21 35 7 Return 2025-01-07 15:24:52.657552 283.9 Beautiful require discuss. +22 33 5 Rental 2025-01-05 15:49:27.469122 270.25 Your claim before record event. +23 25 15 Return 2025-01-06 19:26:09.706831 11.48 College five court realize national usually spend. +24 6 18 Sale 2025-01-02 13:09:13.996161 378.17 Huge recognize career full evidence. +25 34 15 Rental 2025-01-01 13:08:08.892432 92.48 Heart my reach seem. +26 46 12 Sale 2025-01-08 13:15:57.539659 27.63 Never start team on personal. +27 36 18 Sale 2025-01-05 01:42:16.062249 379.57 Contain however hour free understand approach. +28 19 16 Return 2025-01-06 13:52:20.733679 57.23 Town order price without. +29 41 11 Return 2025-01-05 01:54:14.555208 285.55 Director break race method cup reflect. +30 46 14 Sale 2025-01-09 12:33:31.710219 418.72 Describe second suggest side whole summer scene sit. +31 6 15 Return 2025-01-02 01:39:56.841238 234.34 Man talk tax official why each. +32 25 3 Rental 2025-01-03 16:34:24.019198 47.09 Professional fire western yes and rise. +33 50 11 Sale 2025-01-07 03:46:00.440673 21.64 Pick point college art window establish generation. +34 44 15 Sale 2025-01-09 06:11:46.502587 58.81 Training charge sing network practice indicate. +35 11 4 Return 2025-01-04 09:59:38.611101 359.51 Believe time performance former son research. +36 21 2 Sale 2025-01-07 16:45:55.633113 450.69 House success father goal decision. +37 48 8 Rental 2025-01-02 19:30:19.513224 376.06 Will huge current question only laugh. +38 7 7 Return 2025-01-09 07:54:56.861736 266.68 Hot national as rich sense do. +39 18 4 Sale 2025-01-03 00:58:45.780465 10.01 Brother newspaper relate camera. +40 10 8 Return 2025-01-03 21:35:41.805364 498.47 Billion beautiful sister third beyond trip later. +41 4 19 Return 2025-01-08 15:39:15.548741 385.07 Mind late benefit clear box fall. +42 21 14 Rental 2025-01-04 13:22:19.886734 371.96 Arrive a quickly growth cup more growth. +43 29 18 Rental 2025-01-05 10:44:47.594180 248.52 Environment live leader establish page fire smile. +44 15 9 Return 2025-01-08 04:54:54.349731 343.93 Ago able man still because edge. +45 1 6 Sale 2025-01-06 17:28:30.318964 158.97 Forget up senior save similar cut. +46 32 13 Return 2025-01-06 01:04:58.734765 369.9 Operation indicate where head life conference play source. +47 8 2 Sale 2025-01-01 13:21:22.098153 436.27 Stock four look meet follow son no. +48 18 9 Sale 2025-01-08 11:08:54.544866 141.76 West fund attorney eat. +49 37 11 Return 2025-01-05 21:01:37.248513 43.93 Line management mission nation hand enter. +50 24 20 Sale 2025-01-01 08:00:24.211308 208.04 Sort will respond. +51 34 13 Return 2025-01-08 20:41:10.383703 333.91 Order condition body why. +52 48 15 Return 2025-01-09 13:11:09.843066 486.57 Let air place mind through three former. +53 8 1 Rental 2025-01-05 04:30:22.270990 182.64 Page individual look kid stuff memory approach. +54 20 3 Sale 2025-01-01 20:50:45.309585 203.82 Society prepare reduce exist decade. +55 39 15 Sale 2025-01-02 00:24:33.140710 198.32 Approach today way direction thank myself. +56 31 9 Rental 2025-01-05 11:48:09.134273 143.67 Movie whom head allow say. +57 28 5 Sale 2025-01-07 04:17:14.341166 279.41 Action while bed operation family low. +58 46 19 Rental 2025-01-06 03:27:56.401884 489.29 Partner begin imagine pressure meet Republican some each. +59 43 9 Return 2025-01-09 07:52:23.457044 75.11 Among the least several. +60 47 13 Rental 2025-01-08 09:47:30.655247 21.0 Conference history may accept. +\. + +COPY "Rentals" FROM stdin; +1 21 2025-01-02 17:17:01.038259 2025-01-04 09:27:31.353393 2025-01-02 17:17:01.038259 2025-01-04 09:27:31.353393 1 day, 16:10:30.315134 +2 36 2025-01-05 19:39:20.860763 2025-01-06 20:27:26.861075 2025-01-05 19:39:20.860763 2025-01-06 20:27:26.861075 1 day, 0:48:06.000312 +3 60 2025-01-04 21:08:17.008730 2025-01-08 19:15:09.054021 2025-01-04 21:08:17.008730 2025-01-08 19:15:09.054021 3 days, 22:06:52.045291 +4 57 2025-01-06 15:07:27.892103 2025-01-08 21:54:50.517507 2025-01-06 15:07:27.892103 2025-01-08 21:54:50.517507 2 days, 6:47:22.625404 +5 19 2025-01-03 20:32:32.270051 2025-01-04 22:23:22.631980 2025-01-03 20:32:32.270051 2025-01-04 22:23:22.631980 1 day, 1:50:50.361929 +6 3 2025-01-07 17:31:41.074136 2025-01-07 19:47:05.603302 2025-01-07 17:31:41.074136 2025-01-07 19:47:05.603302 2:15:24.529166 +7 43 2025-01-09 11:14:08.299994 2025-01-09 12:22:00.997263 2025-01-09 11:14:08.299994 2025-01-09 12:22:00.997263 1:07:52.697269 +8 59 2025-01-06 11:50:20.545521 2025-01-08 17:56:03.290966 2025-01-06 11:50:20.545521 2025-01-08 17:56:03.290966 2 days, 6:05:42.745445 +9 7 2025-01-08 13:02:09.582545 2025-01-09 01:06:22.105703 2025-01-08 13:02:09.582545 2025-01-09 01:06:22.105703 12:04:12.523158 +10 60 2025-01-09 14:09:05.837723 2025-01-09 14:26:47.625353 2025-01-09 14:09:05.837723 2025-01-09 14:26:47.625353 0:17:41.787630 +11 20 2025-01-08 19:41:12.490849 2025-01-08 23:52:09.761080 2025-01-08 19:41:12.490849 2025-01-08 23:52:09.761080 4:10:57.270231 +12 60 2025-01-09 10:26:39.846213 2025-01-09 12:45:53.057719 2025-01-09 10:26:39.846213 2025-01-09 12:45:53.057719 2:19:13.211506 +13 14 2025-01-04 05:25:21.449598 2025-01-05 05:29:53.512150 2025-01-04 05:25:21.449598 2025-01-05 05:29:53.512150 1 day, 0:04:32.062552 +14 50 2025-01-07 21:00:32.884118 2025-01-08 19:56:00.542939 2025-01-07 21:00:32.884118 2025-01-08 19:56:00.542939 22:55:27.658821 +15 7 2025-01-04 17:56:55.975461 2025-01-06 07:20:35.402320 2025-01-04 17:56:55.975461 2025-01-06 07:20:35.402320 1 day, 13:23:39.426859 +16 30 2025-01-01 07:43:41.525616 2025-01-01 11:59:54.787428 2025-01-01 07:43:41.525616 2025-01-01 11:59:54.787428 4:16:13.261812 +17 8 2025-01-08 01:14:50.247716 2025-01-08 03:00:18.033791 2025-01-08 01:14:50.247716 2025-01-08 03:00:18.033791 1:45:27.786075 +18 53 2025-01-04 23:09:58.226653 2025-01-07 12:42:25.366726 2025-01-04 23:09:58.226653 2025-01-07 12:42:25.366726 2 days, 13:32:27.140073 +19 10 2025-01-08 14:47:41.353557 2025-01-09 05:13:52.863668 2025-01-08 14:47:41.353557 2025-01-09 05:13:52.863668 14:26:11.510111 +20 29 2025-01-08 00:06:28.247108 2025-01-08 21:00:25.535046 2025-01-08 00:06:28.247108 2025-01-08 21:00:25.535046 20:53:57.287938 +21 45 2025-01-01 03:19:14.665370 2025-01-06 15:09:50.270534 2025-01-01 03:19:14.665370 2025-01-06 15:09:50.270534 5 days, 11:50:35.605164 +22 40 2025-01-06 12:40:02.617011 2025-01-07 06:05:40.409848 2025-01-06 12:40:02.617011 2025-01-07 06:05:40.409848 17:25:37.792837 +23 6 2025-01-02 19:58:34.684974 2025-01-06 19:24:49.730970 2025-01-02 19:58:34.684974 2025-01-06 19:24:49.730970 3 days, 23:26:15.045996 +24 41 2025-01-06 01:40:23.089083 2025-01-07 16:03:50.691736 2025-01-06 01:40:23.089083 2025-01-07 16:03:50.691736 1 day, 14:23:27.602653 +25 40 2025-01-03 15:30:50.863278 2025-01-06 16:55:14.172005 2025-01-03 15:30:50.863278 2025-01-06 16:55:14.172005 3 days, 1:24:23.308727 +26 41 2025-01-05 21:53:59.869241 2025-01-06 17:34:07.536256 2025-01-05 21:53:59.869241 2025-01-06 17:34:07.536256 19:40:07.667015 +27 44 2025-01-02 18:26:00.111548 2025-01-03 17:16:27.936515 2025-01-02 18:26:00.111548 2025-01-03 17:16:27.936515 22:50:27.824967 +28 38 2025-01-04 22:48:32.464699 2025-01-07 01:43:00.146715 2025-01-04 22:48:32.464699 2025-01-07 01:43:00.146715 2 days, 2:54:27.682016 +29 60 2025-01-04 11:33:22.404860 2025-01-08 22:07:32.443708 2025-01-04 11:33:22.404860 2025-01-08 22:07:32.443708 4 days, 10:34:10.038848 +30 55 2025-01-09 01:08:30.422155 2025-01-09 06:04:16.712306 2025-01-09 01:08:30.422155 2025-01-09 06:04:16.712306 4:55:46.290151 +\. + diff --git a/beta-case-studies/hardware_store/requirements.txt b/beta-case-studies/hardware_store/requirements.txt new file mode 100644 index 0000000..62e3730 --- /dev/null +++ b/beta-case-studies/hardware_store/requirements.txt @@ -0,0 +1,2 @@ +faker +faker-commerce diff --git a/beta-case-studies/hardware_store/schema.sql b/beta-case-studies/hardware_store/schema.sql new file mode 100644 index 0000000..0ebee02 --- /dev/null +++ b/beta-case-studies/hardware_store/schema.sql @@ -0,0 +1,61 @@ +DROP SCHEMA IF EXISTS "Hardware Store" CASCADE; +CREATE SCHEMA "Hardware Store"; +SET search_path = "Hardware Store"; + +-- Store Locations Table +CREATE TABLE "Store Locations" ( + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + name TEXT NOT NULL, + address TEXT +); + +-- Customers Table +CREATE TABLE "Customers" ( + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + first_name TEXT NOT NULL, + last_name TEXT NOT NULL, + email TEXT UNIQUE, + phone TEXT, + address TEXT +); + +-- Assets Table: Stores asset details +CREATE TABLE "Assets" ( + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + name TEXT NOT NULL, + serial_number TEXT NOT NULL UNIQUE, + rental_price NUMERIC(10, 2), -- Standard rental price + sale_price NUMERIC(10, 2), -- Optional sale price + rental_period TEXT, -- Daily, Weekly, Monthly + location TEXT, -- Physical location in store + store_id BIGINT NOT NULL REFERENCES "Store Locations"(id) ON DELETE SET NULL +); + +CREATE INDEX idx_assets_store_id ON "Assets" (store_id); + +-- Transactions Table: General transactions for sales, rentals, and returns +CREATE TABLE "Transactions" ( + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + asset_id BIGINT NOT NULL REFERENCES "Assets"(id) ON DELETE CASCADE, + customer_id BIGINT NOT NULL REFERENCES "Customers"(id) ON DELETE SET NULL, + transaction_type TEXT CHECK (transaction_type IN ('Sale', 'Rental', 'Return')), + transaction_date TIMESTAMP WITH TIME ZONE NOT NULL, + total_charge NUMERIC(10, 2), -- Sale price or rental charge + note TEXT +); + +CREATE INDEX idx_transactions_asset_id ON "Transactions" (asset_id); +CREATE INDEX idx_transactions_customer_id ON "Transactions" (customer_id); + +-- Rentals Table: Tracks rental-specific details +CREATE TABLE "Rentals" ( + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + transaction_id BIGINT NOT NULL REFERENCES "Transactions"(id) ON DELETE CASCADE, + rental_start TIMESTAMP WITH TIME ZONE, + rental_end TIMESTAMP WITH TIME ZONE, + time_out TIMESTAMP WITH TIME ZONE, + time_in TIMESTAMP WITH TIME ZONE, + rental_time INTERVAL +); + +CREATE INDEX idx_rentals_transaction_id ON "Rentals" (transaction_id); diff --git a/beta-case-studies/museum_exhibits/README.md b/beta-case-studies/museum_exhibits/README.md new file mode 100644 index 0000000..182ad60 --- /dev/null +++ b/beta-case-studies/museum_exhibits/README.md @@ -0,0 +1,72 @@ +# Museum Exhabits sample data + +This sample dataset represents a museum managing their assets and exhibits across multiple locations. + +```mermaid +%% https://mermaid.js.org/syntax/entityRelationshipDiagram.html + +erDiagram + "Acquisition Types" { + BIGINT id PK + string type_name + string description + } + + "Collections" { + BIGINT id PK + string name + string description + } + + "Locations" { + BIGINT id PK + string name + string address + } + + "Exhibits" { + BIGINT id PK + string name + DATE start_date + DATE end_date + BIGINT location_id FK + BOOLEAN featured + string description + } + + "Items" { + BIGINT id PK + string name + string serial_number + DATE acquisition_date + BIGINT acquisition_type_id FK + BIGINT collection_id FK + BIGINT exhibit_id FK + } + +%% Relationships +%% See: https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax + "Exhibits" ||--|| "Locations" : "location_id" + "Items" ||--|| "Acquisition Types" : "acquisition_type_id" + "Items" ||--|| "Collections" : "collection_id" + "Items" ||--|| "Exhibits" : "exhibit_id" + +``` + + +## Loading Data + +The generated SQL file, `generate_data/load_data.sql`, contains all the necessary COPY commands to import data into your database. The data (and the load data file) are produced by the `generate_data.py` file, which can be adjusted and re-run to alter the data if needed. + +Load the data into a locally-running Mathesar instance like this: + +```shell +# First load the schema and tables +docker exec -i mathesar_dev_db bash -c 'psql -U mathesar' < schema.sql +# Then the sample data +docker exec -i mathesar_dev_db bash -c 'psql -U mathesar' < generated_data.sql +``` + +## Development + +The only requirement is to install dependencies with `pip install -r requirements.txt`. diff --git a/beta-case-studies/museum_exhibits/generate_data.py b/beta-case-studies/museum_exhibits/generate_data.py new file mode 100644 index 0000000..19e0367 --- /dev/null +++ b/beta-case-studies/museum_exhibits/generate_data.py @@ -0,0 +1,103 @@ +import os +import random +from faker import Faker +from datetime import datetime, timedelta + +fake = Faker() + +# Number of rows to generate +NUM_LOCATIONS = 5 +NUM_COLLECTIONS = 10 +NUM_ACQUISITION_TYPES = 5 +NUM_EXHIBITS = 15 +NUM_ITEMS = 50 + +# Helper function to clean values for COPY +def clean_value(value): + if value is None: + return r"\N" + if isinstance(value, str): + return value.replace("\t", " ").replace("\n", " ") + return str(value) + +# Adjectives and nouns for dynamic combinations +adjectives = ["Ancient", "Modern", "Historic", "Rare", "Exquisite"] +nouns = ["Art", "Relics", "Artifacts", "Paintings", "Manuscripts", "Sculptures", "Vases", "Bowls"] + +# Table Data Generation +def generate_locations(): + for i in range(1, NUM_LOCATIONS + 1): + yield [i, f"Museum Location {i}", fake.address()] + +def generate_collections(): + for i in range(1, NUM_COLLECTIONS + 1): + name = f"{random.choice(adjectives)} {random.choice(nouns)} Collection" + yield [i, name, fake.text(max_nb_chars=50)] + +def generate_acquisition_types(): + hardcoded_acquisition_types = ["Donation", "Purchase", "Bequest", "Loan", "Exchange"] + for i, name in enumerate(hardcoded_acquisition_types, start=1): + yield [i, name, fake.sentence()] + +def generate_exhibits(location_ids): + for i in range(1, NUM_EXHIBITS + 1): + name = f"{random.choice(adjectives)} {random.choice(nouns)} Exhibit" + start_date = fake.date_this_year() + end_date = ( + fake.date_between_dates(date_start=start_date, date_end=datetime.today() + timedelta(days=180)) + if random.random() < 0.7 else None + ) + yield [ + i, + name, + start_date, + end_date, + random.choice(location_ids), + random.choice([True, False]), + fake.text(max_nb_chars=100) + ] + +def generate_items(acquisition_type_ids, collection_ids, exhibit_ids): + for i in range(1, NUM_ITEMS + 1): + name = f"{random.choice(adjectives)} {random.choice(nouns)}" + acquisition_date = fake.date_this_year() + exhibit_id = random.choice(exhibit_ids) if random.random() < 0.5 else None + yield [ + i, + name, + fake.unique.ean13(), + acquisition_date, + random.choice(acquisition_type_ids), + random.choice(collection_ids), + exhibit_id + ] + +# Generate Data +location_ids = list(range(1, NUM_LOCATIONS + 1)) +collection_ids = list(range(1, NUM_COLLECTIONS + 1)) +acquisition_type_ids = list(range(1, NUM_ACQUISITION_TYPES + 1)) +exhibit_ids = list(range(1, NUM_EXHIBITS + 1)) + +tables = { + "Locations": generate_locations(), + "Collections": generate_collections(), + "Acquisition Types": generate_acquisition_types(), + "Exhibits": generate_exhibits(location_ids), + "Items": generate_items(acquisition_type_ids, collection_ids, exhibit_ids), +} + +# Write to SQL file +sql_file = os.path.join(os.getcwd(), "generated_data.sql") + +with open(sql_file, "w") as f: + f.write('SET search_path="Museum Exhibits";\n\n') + + for table_name, generator in tables.items(): + # Add quotes around table name since it contains spaces + f.write(f'COPY "{table_name}" FROM stdin;\n') + for row in generator: + cleaned_row = "\t".join(map(clean_value, row)) + f.write(f"{cleaned_row}\n") + f.write("\\.\n\n") + +print(f"SQL file generated: {sql_file}") diff --git a/beta-case-studies/museum_exhibits/generated_data.sql b/beta-case-studies/museum_exhibits/generated_data.sql new file mode 100644 index 0000000..b0bcadc --- /dev/null +++ b/beta-case-studies/museum_exhibits/generated_data.sql @@ -0,0 +1,102 @@ +SET search_path="Museum Exhibits"; + +COPY "Locations" FROM stdin; +1 Museum Location 1 3342 Thomas Walk Suite 970 Mitchellville, NM 52630 +2 Museum Location 2 312 Jared Ford Suite 913 South Nicholas, OH 72577 +3 Museum Location 3 59689 Brianna Flats Schmidtfort, MP 28349 +4 Museum Location 4 97612 Janice Isle Suite 251 Smithtown, AS 12945 +5 Museum Location 5 3120 Scott Rapid Apt. 766 North Rebeccaburgh, TN 32185 +\. + +COPY "Collections" FROM stdin; +1 Modern Paintings Collection Thousand whole last certainly leader dog. +2 Ancient Sculptures Collection Sign student would evidence detail short. +3 Historic Sculptures Collection World mother while across big feel. +4 Exquisite Paintings Collection More city difficult Republican ask play. +5 Rare Artifacts Collection Wife yes thing ball long camera that. +6 Exquisite Artifacts Collection Its road them significant serious. +7 Historic Artifacts Collection Affect own vote article really above fast. +8 Exquisite Relics Collection Strong next water involve perform. +9 Ancient Art Collection Ground apply feeling wrong benefit sell. +10 Historic Vases Collection Radio south study goal much. +\. + +COPY "Acquisition Types" FROM stdin; +1 Donation However market few citizen deep measure senior. +2 Purchase Near consider police. +3 Bequest Even then sing continue machine. +4 Loan Lawyer both boy body water pick itself despite. +5 Exchange Contain ten stay analysis word military attorney. +\. + +COPY "Exhibits" FROM stdin; +1 Exquisite Sculptures Exhibit 2025-01-01 2025-02-02 2 True Such give grow drive their character. Mouth scene measure modern deep ability free. +2 Historic Manuscripts Exhibit 2025-01-07 2025-05-17 5 True Threat eye up line front worker red response. Fight option study fear director role show. +3 Modern Relics Exhibit 2025-01-03 2025-04-25 2 True Thank while need half. Score he thank southern community whole. Small art knowledge crime. +4 Exquisite Vases Exhibit 2025-01-07 \N 1 True Fire occur garden ago feel wide. Stage them instead lose college discuss reveal. +5 Modern Art Exhibit 2025-01-01 2025-04-16 4 True Large huge could research happy responsibility car. +6 Ancient Paintings Exhibit 2025-01-02 2025-01-07 2 True Study human view sometimes. School card what. +7 Historic Art Exhibit 2025-01-08 2025-01-30 4 True Idea prevent my indeed this yet. Big audience today popular media. +8 Rare Vases Exhibit 2025-01-02 2025-03-05 2 True Fall require activity science ability. Music term red. +9 Rare Artifacts Exhibit 2025-01-05 2025-04-21 2 True For doctor point. Tough serve grow water avoid determine. Increase near glass southern fly. +10 Historic Paintings Exhibit 2025-01-08 2025-06-02 4 False Simply skin billion clearly option table determine. Detail whole to later type short. +11 Historic Manuscripts Exhibit 2025-01-06 2025-06-22 4 False Return help deep me family. Plan response send contain subject. +12 Rare Paintings Exhibit 2025-01-08 2025-01-31 2 True Cultural even run yes with. +13 Exquisite Relics Exhibit 2025-01-03 2025-01-19 4 False Loss any represent window now argue. Training into majority rise person respond thought. +14 Historic Artifacts Exhibit 2025-01-01 \N 4 True Reveal member which without everyone green fear. Beyond me view quality seem. +15 Ancient Art Exhibit 2025-01-04 2025-04-27 3 True Child best business conference system. Face us work. Detail note body during sure feel often bar. +\. + +COPY "Items" FROM stdin; +1 Ancient Artifacts 7861969220297 2025-01-05 3 2 15 +2 Ancient Vases 8820074493636 2025-01-01 5 9 4 +3 Ancient Artifacts 2625026956919 2025-01-01 5 10 12 +4 Historic Bowls 8695494022694 2025-01-08 1 1 \N +5 Ancient Sculptures 8518672551345 2025-01-07 1 10 13 +6 Historic Paintings 3630925335627 2025-01-03 2 2 \N +7 Historic Paintings 8069955695053 2025-01-06 5 6 11 +8 Ancient Bowls 3505984304054 2025-01-03 4 7 \N +9 Exquisite Manuscripts 7526113518926 2025-01-06 2 4 10 +10 Historic Paintings 2125602538121 2025-01-02 1 1 2 +11 Modern Relics 4707548142853 2025-01-01 2 7 8 +12 Ancient Artifacts 1532720226921 2025-01-05 4 1 \N +13 Rare Bowls 8058055853272 2025-01-06 4 1 9 +14 Rare Relics 1999697582984 2025-01-04 5 10 \N +15 Modern Artifacts 0695161049687 2025-01-06 1 3 11 +16 Historic Sculptures 1846493212600 2025-01-04 2 5 \N +17 Exquisite Paintings 4074847383493 2025-01-05 5 2 8 +18 Rare Relics 8540721566970 2025-01-02 4 6 12 +19 Ancient Vases 0963776290450 2025-01-01 5 2 9 +20 Rare Sculptures 3833419958528 2025-01-05 5 8 1 +21 Rare Sculptures 0950298840362 2025-01-08 5 9 13 +22 Ancient Art 0818100697606 2025-01-03 1 2 \N +23 Exquisite Paintings 6690314200704 2025-01-07 3 2 10 +24 Exquisite Bowls 5606147743654 2025-01-06 2 5 11 +25 Modern Paintings 3813534602704 2025-01-06 2 9 \N +26 Rare Paintings 6721744958290 2025-01-07 5 10 2 +27 Historic Art 9485048537991 2025-01-07 3 8 11 +28 Historic Artifacts 9735752321639 2025-01-01 3 6 \N +29 Rare Manuscripts 0327009188684 2025-01-07 5 1 8 +30 Rare Paintings 3876964658185 2025-01-07 3 4 \N +31 Historic Paintings 3572359527899 2025-01-03 5 1 15 +32 Ancient Relics 6759492550756 2025-01-04 3 9 \N +33 Rare Relics 1140458904167 2025-01-07 5 10 3 +34 Exquisite Art 1465923516349 2025-01-05 5 1 14 +35 Historic Vases 3287812094565 2025-01-04 1 3 \N +36 Exquisite Sculptures 1662516081011 2025-01-05 4 7 \N +37 Exquisite Vases 7475174373947 2025-01-06 4 5 12 +38 Rare Paintings 2599395429414 2025-01-02 4 4 13 +39 Historic Art 3098942732209 2025-01-03 5 8 \N +40 Historic Art 6889724096872 2025-01-05 1 10 14 +41 Exquisite Artifacts 4031573040526 2025-01-08 3 10 9 +42 Rare Artifacts 5495800649989 2025-01-03 4 8 \N +43 Modern Manuscripts 5107602652059 2025-01-07 4 10 9 +44 Ancient Artifacts 3348770363312 2025-01-03 5 10 5 +45 Rare Art 9743628810767 2025-01-08 3 4 \N +46 Modern Artifacts 7318515963097 2025-01-07 4 6 \N +47 Exquisite Paintings 8794344557673 2025-01-06 5 5 \N +48 Historic Sculptures 7775970437400 2025-01-06 2 10 \N +49 Ancient Artifacts 2825435332964 2025-01-04 1 7 \N +50 Modern Artifacts 4624956992552 2025-01-04 3 8 \N +\. + diff --git a/beta-case-studies/museum_exhibits/requirements.txt b/beta-case-studies/museum_exhibits/requirements.txt new file mode 100644 index 0000000..62e3730 --- /dev/null +++ b/beta-case-studies/museum_exhibits/requirements.txt @@ -0,0 +1,2 @@ +faker +faker-commerce diff --git a/beta-case-studies/museum_exhibits/schema.sql b/beta-case-studies/museum_exhibits/schema.sql new file mode 100644 index 0000000..879809b --- /dev/null +++ b/beta-case-studies/museum_exhibits/schema.sql @@ -0,0 +1,42 @@ +DROP SCHEMA IF EXISTS "Museum Exhibits" CASCADE; +CREATE SCHEMA "Museum Exhibits"; +SET search_path = "Museum Exhibits"; + + +create table "Acquisition Types" ( + id bigint primary key generated always as identity, + type_name text not null unique, + description text +); + +create table "Collections" ( + id bigint primary key generated always as identity, + name text not null, + description text +); + +create table "Locations" ( + id bigint primary key generated always as identity, + name text not null, + address text +); + +create table "Exhibits" ( + id bigint primary key generated always as identity, + name text not null, + start_date date not null, + end_date date, + location_id bigint not null references "Locations" (id), + featured boolean default false, + description text +); + +create table "Items" ( + id bigint primary key generated always as identity, + name text not null, + serial_number text not null unique, + acquisition_date date not null, + acquisition_type_id bigint not null references "Acquisition Types" (id), + collection_id bigint not null references "Collections" (id), + exhibit_id bigint references "Exhibits" (id) +); diff --git a/beta-case-studies/screenshot-generation/Dockerfile b/beta-case-studies/screenshot-generation/Dockerfile new file mode 100644 index 0000000..4a6131e --- /dev/null +++ b/beta-case-studies/screenshot-generation/Dockerfile @@ -0,0 +1,13 @@ +# Dockerfile +FROM mcr.microsoft.com/playwright:v1.49.1-noble + +WORKDIR /tests +COPY . . + +RUN npm install -D @playwright/test@latest + +# Entry point script +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/beta-case-studies/screenshot-generation/entrypoint.sh b/beta-case-studies/screenshot-generation/entrypoint.sh new file mode 100644 index 0000000..c0bbe13 --- /dev/null +++ b/beta-case-studies/screenshot-generation/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# entrypoint.sh + +npm install -D @playwright/test@latest + +# Run tests +npx playwright test "$@" + +# Ensure test results have correct permissions +chmod -R 777 test-results diff --git a/beta-case-studies/screenshot-generation/justfile b/beta-case-studies/screenshot-generation/justfile new file mode 100644 index 0000000..27016c2 --- /dev/null +++ b/beta-case-studies/screenshot-generation/justfile @@ -0,0 +1,3 @@ +run: + docker build -t playwright-tests . + docker run -v $(pwd)/test-results:/tests/test-results --network host playwright-tests diff --git a/beta-case-studies/screenshot-generation/package-lock.json b/beta-case-studies/screenshot-generation/package-lock.json new file mode 100644 index 0000000..e2cbe5f --- /dev/null +++ b/beta-case-studies/screenshot-generation/package-lock.json @@ -0,0 +1,71 @@ +{ + "name": "screenshot-generation", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@playwright/test": "^1.49.1" + } + }, + "node_modules/@playwright/test": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", + "dev": true, + "dependencies": { + "playwright": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", + "dev": true, + "dependencies": { + "playwright-core": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + } + } +} diff --git a/beta-case-studies/screenshot-generation/package.json b/beta-case-studies/screenshot-generation/package.json new file mode 100644 index 0000000..a34af26 --- /dev/null +++ b/beta-case-studies/screenshot-generation/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "@playwright/test": "^1.49.1" + } +} diff --git a/beta-case-studies/screenshot-generation/playwright.config.ts b/beta-case-studies/screenshot-generation/playwright.config.ts new file mode 100644 index 0000000..75d1e95 --- /dev/null +++ b/beta-case-studies/screenshot-generation/playwright.config.ts @@ -0,0 +1,11 @@ +// playwright.config.ts +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: './tests', + outputDir: './test-results', + use: { + baseURL: 'http://localhost:8000', + screenshot: 'on', + }, +}); diff --git a/beta-case-studies/screenshot-generation/tests/init.spec.ts b/beta-case-studies/screenshot-generation/tests/init.spec.ts new file mode 100644 index 0000000..6db25b9 --- /dev/null +++ b/beta-case-studies/screenshot-generation/tests/init.spec.ts @@ -0,0 +1,12 @@ +// tests/screenshot.spec.ts +import { test, expect } from '@playwright/test'; + +test('capture homepage screenshot', async ({ page }) => { + await page.goto('/'); + + // Take screenshot and save to test-results + await page.screenshot({ + path: 'test-results/homepage.png', + fullPage: true + }); +}); diff --git a/beta-case-studies/screenshot-generation/tests/test-1.spec.ts b/beta-case-studies/screenshot-generation/tests/test-1.spec.ts new file mode 100644 index 0000000..044d64c --- /dev/null +++ b/beta-case-studies/screenshot-generation/tests/test-1.spec.ts @@ -0,0 +1,69 @@ +import { test, expect } from '@playwright/test'; + +test('login', async ({ page }) => { + await page.goto("/") + + // Resize window to 1280 x 1320 + await page.setViewportSize({ width: 1280, height: 1320 }); + + // Click on #id_username + await page.click('#id_username'); + // Fill "admin" on #id_username + await page.fill('#id_username', 'admin'); + // Fill "password" on #id_password + await page.fill('#id_password', 'password'); + // Click on