{"id":30810483,"url":"https://github.com/shyinlim/test_result_dashboard_streamlit_gemini","last_synced_at":"2026-04-09T11:01:55.916Z","repository":{"id":313381641,"uuid":"1049133051","full_name":"taurus5650/test_result_dashboard_streamlit_gemini","owner":"taurus5650","description":"A lightweight dashboard to view and analyze test automation results. Built with Streamlit + PostgreSQL, and powered by AI (Gemini) to help debug test failures faster.","archived":false,"fork":false,"pushed_at":"2025-09-05T16:18:09.000Z","size":416,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-05T18:35:42.556Z","etag":null,"topics":["ai-testing","artificial-intelligence","automation-testing","docker","docker-compose","gemini","gemini-ai","llm","llm-agent","postgresql","python","quality","quality-assurance","software-testing","streamlit","test-automation","testing-automation","testing-tool","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taurus5650.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-02T14:31:20.000Z","updated_at":"2025-09-05T16:20:11.000Z","dependencies_parsed_at":"2025-09-05T18:35:45.588Z","dependency_job_id":"d71cdd6b-61a7-41b2-bfc0-89ca425a4162","html_url":"https://github.com/taurus5650/test_result_dashboard_streamlit_gemini","commit_stats":null,"previous_names":["taurus5650/test_result_dashboard_streamlit_gemini"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/taurus5650/test_result_dashboard_streamlit_gemini","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taurus5650%2Ftest_result_dashboard_streamlit_gemini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taurus5650%2Ftest_result_dashboard_streamlit_gemini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taurus5650%2Ftest_result_dashboard_streamlit_gemini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taurus5650%2Ftest_result_dashboard_streamlit_gemini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taurus5650","download_url":"https://codeload.github.com/taurus5650/test_result_dashboard_streamlit_gemini/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taurus5650%2Ftest_result_dashboard_streamlit_gemini/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273858876,"owners_count":25180772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-testing","artificial-intelligence","automation-testing","docker","docker-compose","gemini","gemini-ai","llm","llm-agent","postgresql","python","quality","quality-assurance","software-testing","streamlit","test-automation","testing-automation","testing-tool","testing-tools"],"created_at":"2025-09-06T05:13:39.701Z","updated_at":"2025-12-30T21:29:31.739Z","avatar_url":"https://github.com/taurus5650.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Automation Test Result Dashboard\n\nA lightweight dashboard to view and analyze test automation results. \u003cbr\u003e \nBuilt with Streamlit + PostgreSQL, and powered by AI (Gemini) to help debug test failures faster.\n\n* _Medium Article:_ https://medium.com/ai-in-plain-english/less-guessing-a-test-results-dashboard-that-explains-failures-with-ai-731f7747ab2a\n\n## 💫 Result\n\n### Overview\n![overview.jpg](readme/overview.jpg)\n\n### Insights (AI Analysis / Failed Case Details)\n![insights.jpg](readme/insights.jpg)\n\n## ✨ Feature\n\n*   **Test Result Centralization** – See results from all services in one place\n*   **Interactive UI** – A user-friendly web interface to view and filter test execution data\n*   **Analytics** – View trends: fail count, test duration\n*   **AI Insights** – Use Gemini (or other LLMs) to summarize failed logs\n\n## 🧠 Business Value\n\nThis dashboard helps engineering teams to:\n*   **Monitor Testing Quality** – Track fail trends and find unstable test cases over time.\n*   **Catch CI Failures Quickly** – View automation results from all services in one place.\n*   **Speed Up Failure Debugging** – Use LLMs (Gemini, OpenAI) to analyze failed logs and errors.\n*   **Focus on Important Failures** – Easily see P0/P1 failures and reduce noise from flaky tests.\n*   **Improve Team Visibility** – QA, Dev, and PMs all share the same clear testing overview.\n\n\n## 🛠️ Tech Stack\n\n*   **Backend / Dashboard**: Python 3.13, Streamlit\n*   **Database**: PostgreSQL\n*   **Containerization**: Docker, Docker Compose\n\n## 🪧 Diagram\n![diagram.png](readme/diagram.png)\n\n## 🏗️ Project Structure\n\n```commandline\n.\n├── run.py                              # Entry point for the Streamlit dashboard\n├── database/                           # DB helper classes and config\n│   ├── postgresql_helper.py            # Postgres connection logic\n│   ├── config.py                       # Env-based DB config\n│   └── business.py                     # Business logic to fetch and transform data\n├── llm/                                # AI (e.g. Gemini) related helpers\n│   ├── gemini_helper.py                # Gemini API wrapper\n│   └── cache.py                        # Optional local caching\n├── utility/\n│   └── enum.py                         # Shared enums for status types, etc.\n├── deployment/                         # Docker \u0026 Compose configs\n│   ├── Dockerfile                      # Builds dashboard image\n│   ├── docker-compose-dev.yml          # Dev Compose with volumes\n│   ├── docker-compose-prod.yml         # Optional for prod\n│   └── init.sql                        # Initializes DB schema\n├── requirements.txt / poetry.lock / pyproject.toml\n└── README.md\n\n```\n\n## 🚀 Getting Started\n\nUse the steps below to set up and run this project locally.\n\n### Setup Gemini API key\n`deployment/.env`\n![api_key.png](readme/api_key.png)\n\n### Run via Docker Compose\n```commandline\n$ make run-dev\n```\n\n### Create DB Schema (Only run once)\n```sql\nCREATE TABLE IF NOT EXISTS automation_test_result (\n    id SERIAL PRIMARY KEY,\n    service TEXT NOT NULL,\n    service_team TEXT NOT NULL, -- The dev team\n    request_id TEXT,\n    is_rerun BOOLEAN DEFAULT FALSE,\n    trigger_status INT NOT NULL, -- 0=start, 1=success, 2=failed (infra down etc.), 99=unknown\n    trigger_type INT NOT NULL, -- 0=manual, 1=dailyAutomation, 3=ci/cd\n    trigger_user TEXT,\n\n    case_total_count INTEGER DEFAULT 0,\n    success_count INTEGER DEFAULT 0,\n    skip_count INTEGER DEFAULT 0,\n    failure_count INTEGER DEFAULT 0,\n    broken_count INTEGER DEFAULT 0,\n    all_test_records JSONB, -- Record TC name, status (passed, failed, skipped, broken), duration, tags\n    failure_records JSONB, -- Record TC's failure details\n\n    duration FLOAT DEFAULT 0, -- Overall testing duration\n    start_time TIMESTAMP,\n    end_time TIMESTAMP,\n\n    create_time TIMESTAMP DEFAULT NOW(),\n    update_time TIMESTAMP DEFAULT NOW()\n);\n```\n\n### Insert Sample Data (For Local Testing Only)\nTo test the dashboard without running a full test pipeline, you can manually insert sample data into the PostgreSQL database.\nThis is especially useful during development or UI prototyping.\n\n([insert_test_data_sample.sql](readme/insert_test_data_sample.sql))\n```commandline\nINSERT INTO automation_test_result (service, service_team, request_id, is_rerun, trigger_status, trigger_type, trigger_user, case_total_count, success_count, skip_count, failure_count, broken_count, all_test_records, failure_records, duration, start_time, end_time, create_time, update_time) VALUES ('cod_service',  'Payment',  'req-201000',  FALSE,  2,  2,  'Alex',  101,  99,  0,  1,  1,  '[{\"name\": \"test_p1_0\",  \"status\": \"passed\",  \"duration\": 0.55},  {\"name\": \"test_p1_1\",  \"status\": \"passed\",  \"duration\": 0.95},  {\"name\": \"test_p1_2\",  \"status\": \"passed\",  \"duration\": 0.4},  {\"name\": \"test_p1_3\",  \"status\": \"passed\",  \"duration\": 0.46},  {\"name\": \"test_p1_4\",  \"status\": \"passed\",  \"duration\": 1.15},  {\"name\": \"test_p1_5\",  \"status\": \"passed\",  \"duration\": 0.22},  {\"name\": \"test_p1_6\",  \"status\": \"passed\",  \"duration\": 0.84},  {\"name\": \"test_p1_7\",  \"status\": \"passed\",  \"duration\": 0.85},  {\"name\": \"test_p1_8\",  \"status\": \"passed\",  \"duration\": 0.12},  {\"name\": \"test_p1_9\",  \"status\": \"passed\",  \"duration\": 0.1},  {\"name\": \"test_p1_10\",  \"status\": \"passed\",  \"duration\": 0.89},  {\"name\": \"test_p1_11\",  \"status\": \"passed\",  \"duration\": 0.13},  {\"name\": \"test_p1_12\",  \"status\": \"passed\",  \"duration\": 0.38},  {\"name\": \"test_p1_13\",  \"status\": \"passed\",  \"duration\": 0.81},  {\"name\": \"test_p1_14\",  \"status\": \"passed\",  \"duration\": 1.38},  {\"name\": \"test_p1_15\",  \"status\": \"passed\",  \"duration\": 1.17},  {\"name\": \"test_p1_16\",  \"status\": \"passed\",  \"duration\": 0.18},  {\"name\": \"test_p1_17\",  \"status\": \"passed\",  \"duration\": 0.47},  {\"name\": \"test_p1_18\",  \"status\": \"passed\",  \"duration\": 0.66},  {\"name\": \"test_p1_19\",  \"status\": \"passed\",  \"duration\": 0.37},  {\"name\": \"test_p1_20\",  \"status\": \"passed\",  \"duration\": 0.36},  {\"name\": \"test_p1_21\",  \"status\": \"passed\",  \"duration\": 0.13},  {\"name\": \"test_p1_22\",  \"status\": \"passed\",  \"duration\": 1.45},  {\"name\": \"test_p1_23\",  \"status\": \"passed\",  \"duration\": 0.37},  {\"name\": \"test_p1_24\",  \"status\": \"passed\",  \"duration\": 1.26},  {\"name\": \"test_p1_25\",  \"status\": \"passed\",  \"duration\": 0.75},  {\"name\": \"test_p1_26\",  \"status\": \"passed\",  \"duration\": 0.86},  {\"name\": \"test_p1_27\",  \"status\": \"passed\",  \"duration\": 0.93},  {\"name\": \"test_p1_28\",  \"status\": \"passed\",  \"duration\": 1.06},  {\"name\": \"test_p1_29\",  \"status\": \"passed\",  \"duration\": 1.46},  {\"name\": \"test_p1_30\",  \"status\": \"passed\",  \"duration\": 0.85},  {\"name\": \"test_p1_31\",  \"status\": \"passed\",  \"duration\": 0.14},  {\"name\": \"test_p1_32\",  \"status\": \"passed\",  \"duration\": 0.73},  {\"name\": \"test_p1_33\",  \"status\": \"passed\",  \"duration\": 0.27},  {\"name\": \"test_p1_34\",  \"status\": \"passed\",  \"duration\": 0.8},  {\"name\": \"test_p1_35\",  \"status\": \"passed\",  \"duration\": 0.53},  {\"name\": \"test_p1_36\",  \"status\": \"passed\",  \"duration\": 0.68},  {\"name\": \"test_p1_37\",  \"status\": \"passed\",  \"duration\": 0.71},  {\"name\": \"test_p1_38\",  \"status\": \"passed\",  \"duration\": 1.45},  {\"name\": \"test_p1_39\",  \"status\": \"passed\",  \"duration\": 0.98},  {\"name\": \"test_p1_40\",  \"status\": \"passed\",  \"duration\": 0.94},  {\"name\": \"test_p1_41\",  \"status\": \"passed\",  \"duration\": 0.91},  {\"name\": \"test_p1_42\",  \"status\": \"passed\",  \"duration\": 0.5},  {\"name\": \"test_p1_43\",  \"status\": \"passed\",  \"duration\": 1.34},  {\"name\": \"test_p1_44\",  \"status\": \"passed\",  \"duration\": 1.33},  {\"name\": \"test_p1_45\",  \"status\": \"passed\",  \"duration\": 0.57},  {\"name\": \"test_p1_46\",  \"status\": \"passed\",  \"duration\": 1.04},  {\"name\": \"test_p1_47\",  \"status\": \"passed\",  \"duration\": 1.0},  {\"name\": \"test_p1_48\",  \"status\": \"passed\",  \"duration\": 0.4},  {\"name\": \"test_p1_49\",  \"status\": \"passed\",  \"duration\": 0.35},  {\"name\": \"test_p1_50\",  \"status\": \"passed\",  \"duration\": 0.87},  {\"name\": \"test_p1_51\",  \"status\": \"passed\",  \"duration\": 0.89},  {\"name\": \"test_p1_52\",  \"status\": \"passed\",  \"duration\": 0.5},  {\"name\": \"test_p1_53\",  \"status\": \"passed\",  \"duration\": 0.26},  {\"name\": \"test_p1_54\",  \"status\": \"passed\",  \"duration\": 0.64},  {\"name\": \"test_p1_55\",  \"status\": \"passed\",  \"duration\": 0.84},  {\"name\": \"test_p1_56\",  \"status\": \"passed\",  \"duration\": 0.88},  {\"name\": \"test_p1_57\",  \"status\": \"passed\",  \"duration\": 1.13},  {\"name\": \"test_p1_58\",  \"status\": \"passed\",  \"duration\": 0.42},  {\"name\": \"test_p1_59\",  \"status\": \"passed\",  \"duration\": 0.95},  {\"name\": \"test_p1_60\",  \"status\": \"passed\",  \"duration\": 0.13},  {\"name\": \"test_p1_61\",  \"status\": \"passed\",  \"duration\": 0.81},  {\"name\": \"test_p1_62\",  \"status\": \"passed\",  \"duration\": 0.57},  {\"name\": \"test_p1_63\",  \"status\": \"passed\",  \"duration\": 0.44},  {\"name\": \"test_p1_64\",  \"status\": \"passed\",  \"duration\": 1.07},  {\"name\": \"test_p1_65\",  \"status\": \"passed\",  \"duration\": 0.21},  {\"name\": \"test_p1_66\",  \"status\": \"passed\",  \"duration\": 0.1},  {\"name\": \"test_p1_67\",  \"status\": \"passed\",  \"duration\": 0.14},  {\"name\": \"test_p1_68\",  \"status\": \"passed\",  \"duration\": 0.26},  {\"name\": \"test_p1_69\",  \"status\": \"passed\",  \"duration\": 1.06},  {\"name\": \"test_p1_70\",  \"status\": \"passed\",  \"duration\": 0.12},  {\"name\": \"test_p1_71\",  \"status\": \"passed\",  \"duration\": 0.98},  {\"name\": \"test_p1_72\",  \"status\": \"passed\",  \"duration\": 0.77},  {\"name\": \"test_p1_73\",  \"status\": \"passed\",  \"duration\": 1.23},  {\"name\": \"test_p1_74\",  \"status\": \"passed\",  \"duration\": 1.46},  {\"name\": \"test_p1_75\",  \"status\": \"passed\",  \"duration\": 0.72},  {\"name\": \"test_p1_76\",  \"status\": \"passed\",  \"duration\": 0.82},  {\"name\": \"test_p1_77\",  \"status\": \"passed\",  \"duration\": 0.36},  {\"name\": \"test_p1_78\",  \"status\": \"passed\",  \"duration\": 0.68},  {\"name\": \"test_p1_79\",  \"status\": \"passed\",  \"duration\": 0.42},  {\"name\": \"test_p1_80\",  \"status\": \"passed\",  \"duration\": 1.14},  {\"name\": \"test_p1_81\",  \"status\": \"passed\",  \"duration\": 0.71},  {\"name\": \"test_p1_82\",  \"status\": \"passed\",  \"duration\": 1.48},  {\"name\": \"test_p1_83\",  \"status\": \"passed\",  \"duration\": 1.08},  {\"name\": \"test_p1_84\",  \"status\": \"passed\",  \"duration\": 1.18},  {\"name\": \"test_p1_85\",  \"status\": \"passed\",  \"duration\": 1.1},  {\"name\": \"test_p1_86\",  \"status\": \"passed\",  \"duration\": 0.95},  {\"name\": \"test_p1_87\",  \"status\": \"passed\",  \"duration\": 0.4},  {\"name\": \"test_p1_88\",  \"status\": \"passed\",  \"duration\": 1.43},  {\"name\": \"test_p1_89\",  \"status\": \"passed\",  \"duration\": 0.39},  {\"name\": \"test_p1_90\",  \"status\": \"passed\",  \"duration\": 0.97},  {\"name\": \"test_p1_91\",  \"status\": \"passed\",  \"duration\": 1.0},  {\"name\": \"test_p1_92\",  \"status\": \"passed\",  \"duration\": 1.32},  {\"name\": \"test_p1_93\",  \"status\": \"passed\",  \"duration\": 0.19},  {\"name\": \"test_p1_94\",  \"status\": \"passed\",  \"duration\": 0.87},  {\"name\": \"test_p1_95\",  \"status\": \"passed\",  \"duration\": 1.31},  {\"name\": \"test_p1_96\",  \"status\": \"passed\",  \"duration\": 0.17},  {\"name\": \"test_p1_97\",  \"status\": \"passed\",  \"duration\": 0.28},  {\"name\": \"test_p1_98\",  \"status\": \"passed\",  \"duration\": 0.29},  {\"name\": \"test_p0_99\",  \"status\": \"failed\",  \"duration\": 1.22},  {\"name\": \"test_p1_100\",  \"status\": \"broken\",  \"duration\": 0.67}]'::jsonb,  '[{\"name\": \"test_p0_100\",  \"error\": \"AssertionError: expected 200, '[{\"name\": \"test_p0_100\", \"error\": \"AssertionError: expected 200): line 42, in test\"}]'::jsonb, 9.8, '2025-09-05 16:52:00', '2025-09-05 17:01:45', '2025-09-05 12:00:00', '2025-09-05 12:00:00');\nINSERT INTO automation_test_result (service, service_team, request_id, is_rerun, trigger_status, trigger_type, trigger_user, case_total_count, success_count, skip_count, failure_count, broken_count, all_test_records, failure_records, duration, start_time, end_time, create_time, update_time) VALUES ('cod_service',  'Payment',  'req-201001',  FALSE,  2,  1,  'Leo',  82,  70,  5,  4,  3,  '[{\"name\": \"test_p1_1\",  \"status\": \"passed\",  \"duration\": 0.81},  {\"name\": \"test_p1_2\",  \"status\": \"passed\",  \"duration\": 1.06},  {\"name\": \"test_p1_3\",  \"status\": \"passed\",  \"duration\": 0.68},  {\"name\": \"test_p1_4\",  \"status\": \"passed\",  \"duration\": 1.32},  {\"name\": \"test_p1_5\",  \"status\": \"passed\",  \"duration\": 0.8},  {\"name\": \"test_p1_6\",  \"status\": \"passed\",  \"duration\": 1.08},  {\"name\": \"test_p1_7\",  \"status\": \"passed\",  \"duration\": 0.97},  {\"name\": \"test_p1_8\",  \"status\": \"passed\",  \"duration\": 0.92},  {\"name\": \"test_p1_9\",  \"status\": \"passed\",  \"duration\": 0.84},  {\"name\": \"test_p1_10\",  \"status\": \"passed\",  \"duration\": 0.31},  {\"name\": \"test_p1_11\",  \"status\": \"passed\",  \"duration\": 1.21},  {\"name\": \"test_p1_12\",  \"status\": \"passed\",  \"duration\": 0.81},  {\"name\": \"test_p1_13\",  \"status\": \"passed\",  \"duration\": 1.13},  {\"name\": \"test_p1_14\",  \"status\": \"passed\",  \"duration\": 0.86},  {\"name\": \"test_p1_15\",  \"status\": \"passed\",  \"duration\": 0.34},  {\"name\": \"test_p1_16\",  \"status\": \"passed\",  \"duration\": 0.19},  {\"name\": \"test_p1_17\",  \"status\": \"passed\",  \"duration\": 1.17},  {\"name\": \"test_p1_18\",  \"status\": \"passed\",  \"duration\": 0.39},  {\"name\": \"test_p1_19\",  \"status\": \"passed\",  \"duration\": 1.46},  {\"name\": \"test_p1_20\",  \"status\": \"passed\",  \"duration\": 1.41},  {\"name\": \"test_p1_21\",  \"status\": \"passed\",  \"duration\": 1.33},  {\"name\": \"test_p1_22\",  \"status\": \"passed\",  \"duration\": 0.64},  {\"name\": \"test_p1_23\",  \"status\": \"passed\",  \"duration\": 1.19},  {\"name\": \"test_p1_24\",  \"status\": \"passed\",  \"duration\": 0.53},  {\"name\": \"test_p1_25\",  \"status\": \"passed\",  \"duration\": 0.34},  {\"name\": \"test_p1_26\",  \"status\": \"passed\",  \"duration\": 1.24},  {\"name\": \"test_p1_27\",  \"status\": \"passed\",  \"duration\": 1.12},  {\"name\": \"test_p1_28\",  \"status\": \"passed\",  \"duration\": 0.69},  {\"name\": \"test_p1_29\",  \"status\": \"passed\",  \"duration\": 0.85},  {\"name\": \"test_p1_30\",  \"status\": \"passed\",  \"duration\": 0.74},  {\"name\": \"test_p1_31\",  \"status\": \"passed\",  \"duration\": 1.32},  {\"name\": \"test_p1_32\",  \"status\": \"passed\",  \"duration\": 0.42},  {\"name\": \"test_p1_33\",  \"status\": \"passed\",  \"duration\": 0.49},  {\"name\": \"test_p1_34\",  \"status\": \"passed\",  \"duration\": 1.1},  {\"name\": \"test_p1_35\",  \"status\": \"passed\",  \"duration\": 1.29},  {\"name\": \"test_p1_36\",  \"status\": \"passed\",  \"duration\": 0.49},  {\"name\": \"test_p1_37\",  \"status\": \"passed\",  \"duration\": 0.28},  {\"name\": \"test_p1_38\",  \"status\": \"passed\",  \"duration\": 0.96},  {\"name\": \"test_p1_39\",  \"status\": \"passed\",  \"duration\": 0.24},  {\"name\": \"test_p1_40\",  \"status\": \"passed\",  \"duration\": 1.28},  {\"name\": \"test_p1_41\",  \"status\": \"passed\",  \"duration\": 1.0},  {\"name\": \"test_p1_42\",  \"status\": \"passed\",  \"duration\": 0.48},  {\"name\": \"test_p1_43\",  \"status\": \"passed\",  \"duration\": 0.12},  {\"name\": \"test_p1_44\",  \"status\": \"passed\",  \"duration\": 0.34},  {\"name\": \"test_p1_45\",  \"status\": \"passed\",  \"duration\": 0.22},  {\"name\": \"test_p1_46\",  \"status\": \"passed\",  \"duration\": 0.87},  {\"name\": \"test_p1_47\",  \"status\": \"passed\",  \"duration\": 0.18},  {\"name\": \"test_p1_48\",  \"status\": \"passed\",  \"duration\": 0.79},  {\"name\": \"test_p1_49\",  \"status\": \"passed\",  \"duration\": 0.19},  {\"name\": \"test_p1_50\",  \"status\": \"passed\",  \"duration\": 0.29},  {\"name\": \"test_p1_51\",  \"status\": \"passed\",  \"duration\": 0.31},  {\"name\": \"test_p1_52\",  \"status\": \"passed\",  \"duration\": 1.34},  {\"name\": \"test_p1_53\",  \"status\": \"passed\",  \"duration\": 0.94},  {\"name\": \"test_p1_54\",  \"status\": \"passed\",  \"duration\": 0.5},  {\"name\": \"test_p1_55\",  \"status\": \"passed\",  \"duration\": 0.86},  {\"name\": \"test_p1_56\",  \"status\": \"passed\",  \"duration\": 1.37},  {\"name\": \"test_p1_57\",  \"status\": \"passed\",  \"duration\": 0.31},  {\"name\": \"test_p1_58\",  \"status\": \"passed\",  \"duration\": 0.18},  {\"name\": \"test_p1_59\",  \"status\": \"passed\",  \"duration\": 1.13},  {\"name\": \"test_p1_60\",  \"status\": \"passed\",  \"duration\": 1.08},  {\"name\": \"test_p1_61\",  \"status\": \"passed\",  \"duration\": 1.15},  {\"name\": \"test_p1_62\",  \"status\": \"passed\",  \"duration\": 0.58},  {\"name\": \"test_p1_63\",  \"status\": \"passed\",  \"duration\": 0.27},  {\"name\": \"test_p1_64\",  \"status\": \"passed\",  \"duration\": 1.3},  {\"name\": \"test_p1_65\",  \"status\": \"passed\",  \"duration\": 0.46},  {\"name\": \"test_p1_66\",  \"status\": \"passed\",  \"duration\": 1.17},  {\"name\": \"test_p1_67\",  \"status\": \"passed\",  \"duration\": 1.03},  {\"name\": \"test_p1_68\",  \"status\": \"passed\",  \"duration\": 0.71},  {\"name\": \"test_p1_69\",  \"status\": \"passed\",  \"duration\": 1.13},  {\"name\": \"test_p1_70\",  \"status\": \"passed\",  \"duration\": 0.69},  {\"name\": \"test_p0_71\",  \"status\": \"skipped\",  \"duration\": 0.0},  {\"name\": \"test_p0_72\",  \"status\": \"skipped\",  \"duration\": 0.0},  {\"name\": \"test_p0_73\",  \"status\": \"skipped\",  \"duration\": 0.0},  {\"name\": \"test_p0_74\",  \"status\": \"skipped\",  \"duration\": 0.0},  {\"name\": \"test_p0_75\",  \"status\": \"skipped\",  \"duration\": 0.0},  {\"name\": \"test_p0_76\",  \"status\": \"failed\",  \"duration\": 0.28},  {\"name\": \"test_p0_77\",  \"status\": \"failed\",  \"duration\": 1.03},  {\"name\": \"test_p0_78\",  \"status\": \"failed\",  \"duration\": 1.12},  {\"name\": \"test_p0_79\",  \"status\": \"failed\",  \"duration\": 1.6},  {\"name\": \"test_p1_80\",  \"status\": \"broken\",  \"duration\": 1.05},  {\"name\": \"test_p1_81\",  \"status\": \"broken\",  \"duration\": 1.79},  {\"name\": \"test_p1_82\",  \"status\": \"broken\",  \"duration\": 2.33}]'::jsonb,  '[{\"name\": \"test_p0_101\",  \"error\": \"AssertionError: expected 200, '[{\"name\": \"test_p0_101\", \"error\": \"AssertionError: expected 200): line 42, in test\"}, {\"name\": \"test_p1_102\", \"error\": \"AssertionError: expected 200, got 490\", \"traceback\": \"Traceback (most recent call last): line 43, in test\"}, {\"name\": \"test_p1_103\", \"error\": \"AssertionError: expected 200, got 480\", \"traceback\": \"Traceback (most recent call last): line 44, in test\"}, {\"name\": \"test_p0_104\", \"error\": \"AssertionError: expected 200, got 470\", \"traceback\": \"Traceback (most recent call last): line 45, in test\"}]'::jsonb, 3.5, '2025-09-13 05:15:00', '2025-09-13 05:18:32', '2025-09-05 12:00:00', '2025-09-05 12:00:00');\n... ...\n```\n\n## 🔍 Future Plans / Roadmap\n\n- Login \u0026 Team-level access control\n- Trend charts grouped by tag / test suite\n- Slack / Email alert integration\n- Historical comparison (e.g., what changed since last run)\n- Multi-environment support (test, uat, staging, prod)\n- Full-text search in error messages\n- CSV / JSON export of test results\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyinlim%2Ftest_result_dashboard_streamlit_gemini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshyinlim%2Ftest_result_dashboard_streamlit_gemini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyinlim%2Ftest_result_dashboard_streamlit_gemini/lists"}