<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anderson Yu-Hong Cai</title>
    <description>The latest articles on DEV Community by Anderson Yu-Hong Cai (@andersontsai).</description>
    <link>https://dev.to/andersontsai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1702199%2Feced5350-50a0-4129-93ce-d07a1424c648.jpg</url>
      <title>DEV Community: Anderson Yu-Hong Cai</title>
      <link>https://dev.to/andersontsai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andersontsai"/>
    <language>en</language>
    <item>
      <title>PR-06 at Hacktoberfest: Applying E2E Testing Lessons to Chart.js + Alpha Vantage</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Sun, 26 Oct 2025 08:34:40 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-06-at-hacktoberfest-applying-e2e-testing-lessons-to-chartjs-alpha-vantage-1bl1</link>
      <guid>https://dev.to/andersontsai/pr-06-at-hacktoberfest-applying-e2e-testing-lessons-to-chartjs-alpha-vantage-1bl1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In my previous post, I documented how seven rounds of feedback reshaped my HERE Maps E2E tests. This time, I put those lessons straight to work on a new page—&lt;strong&gt;Chart.js backed by Alpha Vantage&lt;/strong&gt;—aiming to get it right on the first try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Hackathon Starter
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page:&lt;/strong&gt; Chart.js with Alpha Vantage data
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Add a lean, reliable Playwright E2E test suite
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge:&lt;/strong&gt; Avoid the “write everything, then refactor” trap&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Temptation I Skipped
&lt;/h2&gt;

&lt;p&gt;Without the HERE Maps experience, I would have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loaded the page for every test (8 tests → 8 loads)
&lt;/li&gt;
&lt;li&gt;Checked static HTML (titles, buttons, icons)
&lt;/li&gt;
&lt;li&gt;Verified &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags and versions
&lt;/li&gt;
&lt;li&gt;Simulated flaky error scenarios
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…which is exactly the bucket of things maintainers asked me to remove last time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the Lessons — From the Start
&lt;/h2&gt;

&lt;p&gt;Here’s what I did instead, upfront:&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Shared Page Pattern
&lt;/h3&gt;

&lt;p&gt;Create the page once in &lt;code&gt;beforeAll&lt;/code&gt; and reuse it across tests.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Effect:&lt;/strong&gt; 8 potential page loads → &lt;strong&gt;1&lt;/strong&gt; (≈ −87%).&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Focus on Core Functionality
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Not testing&lt;/strong&gt;: titles, button labels, Font Awesome, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags, descriptive copy.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do test&lt;/strong&gt;: chart renders with data, correct labels/points count, and observable behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Precise Data Assertions
&lt;/h3&gt;

&lt;p&gt;Where possible, assert exact values (not broad ranges). If data varies, assert deterministic transforms (e.g., label counts, date ordering, first/last point mapping).&lt;/p&gt;

&lt;h3&gt;
  
  
  4) API Key Strategy
&lt;/h3&gt;

&lt;p&gt;Instead of testing fallbacks, I let the test fail fast when the &lt;strong&gt;Alpha Vantage API key is invalid&lt;/strong&gt;. That surfaces configuration issues immediately and keeps the suite honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Test Structure
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test 1:&lt;/strong&gt; Page loads once and initializes the chart
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test 2:&lt;/strong&gt; Data → chart pipeline works (labels/points count, x–y mapping)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test 3:&lt;/strong&gt; Integrity checks (e.g., newest label aligns with latest data; legend present; canvas is drawn)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Deliberately no static DOM/script/version checks, and no unreliable error simulations.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance &amp;amp; Scope — If vs. Actual
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Old Habit (Hypothetical)&lt;/th&gt;
&lt;th&gt;Actual PR&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test count&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;−62%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page loads&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;−87%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoC&lt;/td&gt;
&lt;td&gt;~230&lt;/td&gt;
&lt;td&gt;~110&lt;/td&gt;
&lt;td&gt;−53%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;~15s&lt;/td&gt;
&lt;td&gt;~8.4s&lt;/td&gt;
&lt;td&gt;−44%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review rounds&lt;/td&gt;
&lt;td&gt;2–3&lt;/td&gt;
&lt;td&gt;Likely 1&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  PR Communication (What I Wrote)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Sorry for the late PR! After your feedback on the HERE Maps tests (#1457), I wanted to apply those optimizations here before submitting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using a shared page to reduce page loads
&lt;/li&gt;
&lt;li&gt;Removing static element/script checks
&lt;/li&gt;
&lt;li&gt;Focusing on core functionality and precise assertions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy to adjust anything further if needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Why this works:&lt;/strong&gt; it explains the delay, shows growth, lists concrete improvements, and stays collaborative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-Side: Two PRs, Different Approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HERE Maps PR (#1457):&lt;/strong&gt;
7 tests → 7 feedback points → heavy refactor → final 3 tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chart.js PR (#1489):&lt;/strong&gt;
Started with the optimized pattern → 3 focused tests → expecting minimal feedback.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transfer learning matters.&lt;/strong&gt; Yesterday’s feedback is today’s checklist.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preventive design beats cleanup.&lt;/strong&gt; Do less, better, earlier.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test what users see, not implementation details.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail fast on config (API keys).&lt;/strong&gt; It saves everyone time.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communicate like a teammate.&lt;/strong&gt; Own trade-offs and invite discussion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HERE Maps E2E PR: &lt;a href="https://github.com/sahat/hackathon-starter/pull/1473" rel="noopener noreferrer"&gt;https://github.com/sahat/hackathon-starter/pull/1473&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Chart.js E2E PR: &lt;a href="https://github.com/sahat/hackathon-starter/pull/1489" rel="noopener noreferrer"&gt;https://github.com/sahat/hackathon-starter/pull/1489&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Playwright Docs: &lt;a href="https://playwright.dev/docs/best-practices" rel="noopener noreferrer"&gt;https://playwright.dev/docs/best-practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Chart.js: &lt;a href="https://www.chartjs.org/" rel="noopener noreferrer"&gt;https://www.chartjs.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Alpha Vantage: &lt;a href="https://www.alphavantage.co/" rel="noopener noreferrer"&gt;https://www.alphavantage.co/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>playwright</category>
      <category>javascript</category>
    </item>
    <item>
      <title>PR-05 at Hacktoberfest: Optimizing HERE Maps E2E Tests and Handling PR Feedback</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Sun, 26 Oct 2025 07:46:12 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-05-at-hacktoberfest-optimizing-here-maps-e2e-tests-and-handling-pr-feedback-4l4c</link>
      <guid>https://dev.to/andersontsai/pr-05-at-hacktoberfest-optimizing-here-maps-e2e-tests-and-handling-pr-feedback-4l4c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In open-source projects, writing code is only the first step — communicating with maintainers and iterating based on their feedback is where real growth happens.&lt;br&gt;&lt;br&gt;
This post documents my journey contributing to the &lt;strong&gt;Hackathon Starter&lt;/strong&gt; project, where I implemented and later optimized &lt;strong&gt;HERE Maps E2E tests&lt;/strong&gt; in Playwright following seven rounds of feedback from the project maintainer &lt;strong&gt;Yasharf&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Hackathon Starter
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task:&lt;/strong&gt; Add E2E tests for the HERE Maps API page
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool:&lt;/strong&gt; Playwright
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge:&lt;/strong&gt; The initial PR worked but was inefficient and needed significant refactoring
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The First Version — Functional but Inefficient
&lt;/h2&gt;

&lt;p&gt;My first submission included seven test cases covering everything from page elements to map rendering.&lt;br&gt;&lt;br&gt;
However, it had major issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reloaded the page for every test (7× page loads)&lt;/li&gt;
&lt;li&gt;Checked static HTML content (titles, buttons, scripts)&lt;/li&gt;
&lt;li&gt;Contained repetitive logic&lt;/li&gt;
&lt;li&gt;Took ~15 seconds to run
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7 Key Feedback Points and Improvements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Use a Shared Page
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Use shared page to avoid reloading for each test.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Replaced &lt;code&gt;beforeEach&lt;/code&gt; with &lt;code&gt;beforeAll&lt;/code&gt; to reuse the same page instance.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Result:&lt;/strong&gt; Page loads reduced from 7 → 1 (-86%).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2–3. Remove Static Checks
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Drop static page components check.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;“Drop script version check.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Removed unnecessary tests for static HTML and script tags — E2E tests should focus on &lt;em&gt;user behavior&lt;/em&gt;, not layout or boilerplate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Verify Exact Values
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Verify hardcoded expected values.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Replaced fuzzy range checks (e.g., 2–4 miles) with precise expected results (&lt;code&gt;toBe(2.85)&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Skip Error Scenario
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Skip error scenario test.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Removed artificial error interception — such cases belong in unit or integration tests, not end-to-end.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  6. Reframe API Key Test
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Frame as tiles loading test.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Since HERE Maps uses CDN caching, invalid API keys can still load tiles from cache (returning &lt;code&gt;200 OK&lt;/code&gt;).&lt;br&gt;&lt;br&gt;
Reframed the test to verify &lt;em&gt;tile loading success&lt;/em&gt; instead of API key validity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  7. Technical Limitation — Map Details
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Check expected Seattle values (coordinates, markers, etc.).”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
This was the hardest one.&lt;br&gt;&lt;br&gt;
The &lt;code&gt;map&lt;/code&gt; variable is declared with &lt;code&gt;const&lt;/code&gt; inside a script block in the Pug file — making it inaccessible from Playwright.&lt;br&gt;&lt;br&gt;
All attempts (&lt;code&gt;window.map&lt;/code&gt;, DOM lookup, canvas inspection) failed.&lt;br&gt;&lt;br&gt;
In the end, I removed this test and explained the limitation clearly in my PR comments.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Result — Simplified and Efficient
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test cases&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;−57%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page loads&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;−86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code&lt;/td&gt;
&lt;td&gt;190&lt;/td&gt;
&lt;td&gt;66&lt;/td&gt;
&lt;td&gt;−65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;~15s&lt;/td&gt;
&lt;td&gt;~9s&lt;/td&gt;
&lt;td&gt;−40%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The remaining tests now focus purely on core functionality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map initialization and rendering
&lt;/li&gt;
&lt;li&gt;Distance calculation accuracy
&lt;/li&gt;
&lt;li&gt;Tile loading verification
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎯 Define Clear E2E Boundaries
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Test user interactions and functional outcomes
&lt;/li&gt;
&lt;li&gt;❌ Don’t test static HTML or styling
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚡ Optimize for Efficiency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use shared pages or contexts
&lt;/li&gt;
&lt;li&gt;Add listeners before page load
&lt;/li&gt;
&lt;li&gt;Remove redundant tests
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📏 Prefer Precision
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use exact expected values instead of ranges
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧩 Handle Technical Limits Gracefully
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Try multiple approaches
&lt;/li&gt;
&lt;li&gt;Avoid modifying production code unnecessarily
&lt;/li&gt;
&lt;li&gt;Communicate clearly when a limitation exists
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💬 Communicate Like a Collaborator
&lt;/h3&gt;

&lt;p&gt;A good PR response acknowledges issues, explains reasoning, and proposes alternatives —  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Happy to discuss alternative approaches.”&lt;br&gt;&lt;br&gt;
goes a long way in maintaining a positive contributor-maintainer relationship.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This contribution taught me that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quality over quantity&lt;/strong&gt; — meaningful tests matter more than many tests
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance is strategic&lt;/strong&gt; — fewer reloads, faster runs
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication is key&lt;/strong&gt; — technical skill and collaboration go hand in hand
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open-source work isn’t just about code — it’s about learning to cooperate, explain trade-offs, and evolve with feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/sahat/hackathon-starter/pull/1473" rel="noopener noreferrer"&gt;Pull Request #1457&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://playwright.dev/docs/best-practices" rel="noopener noreferrer"&gt;Playwright Best Practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.here.com/documentation/maps/" rel="noopener noreferrer"&gt;HERE Maps JavaScript API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>playwright</category>
      <category>javascript</category>
    </item>
    <item>
      <title>PR-04 at Hacktoberfest: Implementing a Domain Validator for Terraform Provider</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Mon, 13 Oct 2025 21:55:02 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-04-at-hacktoberfest-implementing-a-domain-validator-for-terraform-provider-3ii4</link>
      <guid>https://dev.to/andersontsai/pr-04-at-hacktoberfest-implementing-a-domain-validator-for-terraform-provider-3ii4</guid>
      <description>&lt;h1&gt;
  
  
  Implementing a Domain Validator for Terraform Provider
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This is my fourth pull request for the open-source project &lt;a href="https://github.com/The-DevOps-Daily/terraform-provider-validatefx" rel="noopener noreferrer"&gt;terraform-provider-validatefx&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
The issue (#34) asked for a new &lt;code&gt;is_domain&lt;/code&gt; validator to check domain name formats such as &lt;code&gt;example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The goal was straightforward: follow RFC 952 and RFC 1123 to ensure the validator accurately recognizes valid domain names while rejecting malformed inputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The validator (&lt;code&gt;domain.go&lt;/code&gt;) checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overall length (max 253 characters)&lt;/li&gt;
&lt;li&gt;FQDN support (trailing dot allowed)&lt;/li&gt;
&lt;li&gt;Label validation (1–63 characters, no leading or trailing hyphen)&lt;/li&gt;
&lt;li&gt;Character restrictions (letters, digits, hyphens only)&lt;/li&gt;
&lt;li&gt;TLD rules (no all-numeric top-level domains)&lt;/li&gt;
&lt;li&gt;Proper handling for null, empty, and unknown values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple regex was used for label verification:&lt;br&gt;
&lt;code&gt;^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;A total of 24 test cases were added in &lt;code&gt;domain_test.go&lt;/code&gt;, covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Valid domains (simple, subdomains, deep hierarchies)&lt;/li&gt;
&lt;li&gt;Invalid domains (double dots, invalid chars, too long)&lt;/li&gt;
&lt;li&gt;Edge cases (empty string, unknown values, FQDN)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tests run in parallel and verify both pass and fail messages for accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;I also added a Terraform example (&lt;code&gt;main.tf&lt;/code&gt;) containing nine test inputs — four valid and five invalid — showing how users can apply the new validator in real configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Process
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Created a feature branch: &lt;code&gt;feature/domain-validator&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Followed the same structure as existing validators (&lt;code&gt;email&lt;/code&gt;, &lt;code&gt;uuid&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Used &lt;code&gt;go fmt&lt;/code&gt; for formatting and confirmed successful build and tests&lt;/li&gt;
&lt;li&gt;Committed with clear messages:

&lt;ul&gt;
&lt;li&gt;add domain validator&lt;/li&gt;
&lt;li&gt;add tests for domain validator&lt;/li&gt;
&lt;li&gt;add example for domain validator&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Even though the task was similar to my previous validator work, it reinforced best practices in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Following RFC standards&lt;/li&gt;
&lt;li&gt;Writing consistent, well-tested code&lt;/li&gt;
&lt;li&gt;Keeping PRs small and focused&lt;/li&gt;
&lt;li&gt;Maintaining a clean commit history&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reflection
&lt;/h2&gt;

&lt;p&gt;This contribution may seem minor, but it added another essential validator to the Terraform ValidateFX provider.&lt;br&gt;&lt;br&gt;
Step by step, each pull request builds experience, improves confidence, and strengthens understanding of open-source collaboration.&lt;/p&gt;




</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>terraform</category>
      <category>go</category>
    </item>
    <item>
      <title>PR-03 at Hacktoberfest: Implementing a Credit Card Validator for Terraform Provider</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Mon, 13 Oct 2025 05:48:55 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-03-at-hacktoberfest-implementing-a-credit-card-validator-for-terraform-provider-5a6h</link>
      <guid>https://dev.to/andersontsai/pr-03-at-hacktoberfest-implementing-a-credit-card-validator-for-terraform-provider-5a6h</guid>
      <description>&lt;h1&gt;
  
  
  My First Open Source Contribution: Implementing a Credit Card Validator for Terraform Provider
&lt;/h1&gt;

&lt;h2&gt;
  
  
  How It Started
&lt;/h2&gt;

&lt;p&gt;I recently found an interesting GitHub project — &lt;a href="https://github.com/The-DevOps-Daily/terraform-provider-validatefx" rel="noopener noreferrer"&gt;&lt;strong&gt;terraform-provider-validatefx&lt;/strong&gt;&lt;/a&gt;, a Terraform provider that adds validation functions for HCL. One open issue &lt;a href="https://github.com/The-DevOps-Daily/terraform-provider-validatefx/issues/37" rel="noopener noreferrer"&gt;(#37)&lt;/a&gt; asked for a credit card validator. It looked like a great opportunity to learn and make my first open-source pull request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Project
&lt;/h2&gt;

&lt;p&gt;Before coding, I learned how a &lt;strong&gt;Terraform Provider&lt;/strong&gt; works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform is an “Infrastructure as Code” tool by HashiCorp.
&lt;/li&gt;
&lt;li&gt;Providers are plugins that extend Terraform with new resources or functions.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ValidateFX&lt;/strong&gt; provides validation helpers (like &lt;code&gt;validatefx_email()&lt;/code&gt; or &lt;code&gt;validatefx_uuid()&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing the Validator
&lt;/h2&gt;

&lt;p&gt;Each validator follows the same pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement the &lt;code&gt;frameworkvalidator.String&lt;/code&gt; interface.
&lt;/li&gt;
&lt;li&gt;Add descriptions.
&lt;/li&gt;
&lt;li&gt;Write &lt;code&gt;ValidateString()&lt;/code&gt; for actual checks.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I implemented the &lt;strong&gt;Luhn algorithm&lt;/strong&gt; to validate card numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove spaces and hyphens.
&lt;/li&gt;
&lt;li&gt;Ensure 13–19 digits and numeric only.
&lt;/li&gt;
&lt;li&gt;Reject all zeros.
&lt;/li&gt;
&lt;li&gt;Perform Luhn checksum validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Writing Tests
&lt;/h2&gt;

&lt;p&gt;I added comprehensive tests for:&lt;/p&gt;

&lt;p&gt;✅ Valid cards (Visa, MasterCard, Amex)&lt;br&gt;&lt;br&gt;
✅ Formatted inputs (spaces, hyphens)&lt;br&gt;&lt;br&gt;
❌ Invalid cases (checksum, wrong length, letters, all zeros)&lt;br&gt;&lt;br&gt;
and edge cases (empty, null, unknown).&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Line endings:&lt;/strong&gt; Git detected false changes → fixed with &lt;code&gt;core.autocrlf&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration tests:&lt;/strong&gt; some Docker tests failed due to existing repo issues.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unimplemented functions:&lt;/strong&gt; the repo references &lt;code&gt;validatefx_email()&lt;/code&gt; etc., so I focused only on the validator logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Technical:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform Plugin Framework basics.
&lt;/li&gt;
&lt;li&gt;Luhn algorithm logic.
&lt;/li&gt;
&lt;li&gt;Cross-platform setup and test-driven development.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Collaboration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reading existing patterns before adding code.
&lt;/li&gt;
&lt;li&gt;Scoping work to one issue.
&lt;/li&gt;
&lt;li&gt;Communicating clearly in PRs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;My PR included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 new validator file
&lt;/li&gt;
&lt;li&gt;1 complete test file
&lt;/li&gt;
&lt;li&gt;Full Luhn-based validation logic
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;This first contribution taught me both coding and collaboration.&lt;br&gt;&lt;br&gt;
If you want to start with open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick a small, well-defined issue.
&lt;/li&gt;
&lt;li&gt;Understand the project first.
&lt;/li&gt;
&lt;li&gt;Write clear tests.
&lt;/li&gt;
&lt;li&gt;Be patient — every issue is a learning opportunity.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>terraform</category>
      <category>go</category>
    </item>
    <item>
      <title>PR-02 at Hacktoberfest: From Issue to Pull Request: Adding Windows Network Monitoring to SysMood</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Sun, 12 Oct 2025 05:16:53 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-02-at-hacktoberfest-from-issue-to-pull-request-adding-windows-network-monitoring-to-sysmood-1ibf</link>
      <guid>https://dev.to/andersontsai/pr-02-at-hacktoberfest-from-issue-to-pull-request-adding-windows-network-monitoring-to-sysmood-1ibf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, I contributed a Windows-specific &lt;strong&gt;network monitoring feature&lt;/strong&gt; to the open-source project &lt;strong&gt;SysMood&lt;/strong&gt; — a small system stats CLI that originally showed only CPU and memory usage.&lt;br&gt;&lt;br&gt;
This post documents how I went from opening an issue to submitting a pull request, including what I built, the challenges I met, and what I learned along the way.  &lt;/p&gt;

&lt;h5&gt;
  
  
  PR: &lt;a href="https://github.com/RayBreeze/SysMood/pull/8" rel="noopener noreferrer"&gt;https://github.com/RayBreeze/SysMood/pull/8&lt;/a&gt;
&lt;/h5&gt;




&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project:&lt;/strong&gt; SysMood (lightweight CLI system monitor)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Add &lt;em&gt;Network Sent / Received (KB/s)&lt;/em&gt; to the main display
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment:&lt;/strong&gt; Windows (MinGW / g++, CMake)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Opened Issue #7 proposing network monitoring for Hacktoberfest.
&lt;/li&gt;
&lt;li&gt;Created a &lt;code&gt;feature/network-monitor-windows&lt;/code&gt; branch.
&lt;/li&gt;
&lt;li&gt;Implemented logic in &lt;code&gt;network_monitor.h&lt;/code&gt; for quick testing.
&lt;/li&gt;
&lt;li&gt;Adjusted &lt;code&gt;main.cpp&lt;/code&gt; display and “mood” thresholds.
&lt;/li&gt;
&lt;li&gt;Compiled, tested, and fixed bugs repeatedly.
&lt;/li&gt;
&lt;li&gt;Submitted the PR with clear description and &lt;strong&gt;Closes #7&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Used:&lt;/strong&gt; &lt;code&gt;GetIfTable&lt;/code&gt; (from &lt;code&gt;iphlpapi&lt;/code&gt;) to retrieve interface counters.

&lt;ul&gt;
&lt;li&gt;Tried &lt;code&gt;GetIfTable2&lt;/code&gt; for 64-bit stats but reverted for broader compatibility.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Build:&lt;/strong&gt; Requires linking &lt;code&gt;-liphlpapi&lt;/code&gt; (CMake already handles this).
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Filtering:&lt;/strong&gt; Deduplicated interfaces by &lt;code&gt;dwIndex&lt;/code&gt; and ignored inactive ones.
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Overflow Handling:&lt;/strong&gt; Added wrap-around logic since counters are 32-bit.
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Sampling:&lt;/strong&gt; Two readings (3s apart), rate = Δbytes / elapsed time.
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Display:&lt;/strong&gt; Unified units to KB/s with simple thresholds (0, 1, 10, 100, 1000).
&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Challenges &amp;amp; Fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linking Error:&lt;/strong&gt; Fixed by linking &lt;code&gt;-liphlpapi&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header Incompatibility:&lt;/strong&gt; &lt;code&gt;GetIfTable2&lt;/code&gt; unavailable in MinGW → fallback.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timing Bug:&lt;/strong&gt; Corrected order of t0/t1 sampling and interval computation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit Confusion:&lt;/strong&gt; Clarified KB/s vs Kb/s and adjusted mood thresholds.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows IP Helper API quirks and MinGW compatibility details.
&lt;/li&gt;
&lt;li&gt;Importance of documenting quick build commands (&lt;code&gt;g++ ... -liphlpapi&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Counter wrap-around is a real issue in performance stats.
&lt;/li&gt;
&lt;li&gt;Even small contributions benefit from clear issue planning and minimal PR scope.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Future Ideas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Support &lt;code&gt;GetIfTable2&lt;/code&gt; when headers allow (native 64-bit).
&lt;/li&gt;
&lt;li&gt;Move logic into &lt;code&gt;src/network_monitor.cpp&lt;/code&gt; for cleaner structure.
&lt;/li&gt;
&lt;li&gt;Add an optional &lt;code&gt;--network-debug&lt;/code&gt; mode for verbose output.
&lt;/li&gt;
&lt;li&gt;Consider smoother averaging for display (EMA or multi-sample).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This Issue → PR journey helped me understand Windows network monitoring in depth — from API details to linking traps.&lt;br&gt;&lt;br&gt;
For anyone planning similar contributions: start with a well-defined issue, test iteratively, and keep your PRs small and review-friendly.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>cpp</category>
      <category>funnytool</category>
    </item>
    <item>
      <title>PR-01 at Hacktoberfest: Google Maps E2E Testing — for hackathon-starter</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Thu, 09 Oct 2025 23:05:40 +0000</pubDate>
      <link>https://dev.to/andersontsai/pr-01-at-hacktoberfest-google-maps-e2e-testing-for-hackathon-starter-15dk</link>
      <guid>https://dev.to/andersontsai/pr-01-at-hacktoberfest-google-maps-e2e-testing-for-hackathon-starter-15dk</guid>
      <description>&lt;h2&gt;
  
  
  📝 Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, I took on an interesting open-source issue — writing end-to-end (E2E) tests for the &lt;strong&gt;Google Maps integration&lt;/strong&gt; in the &lt;a href="https://github.com/sahat/hackathon-starter" rel="noopener noreferrer"&gt;&lt;code&gt;sahat/hackathon-starter&lt;/code&gt;&lt;/a&gt; project.&lt;br&gt;&lt;br&gt;
What seemed like a simple task turned out to be full of unexpected technical challenges, and through solving them, I gained valuable experience in both testing strategy and open-source collaboration.&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 Project Background
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hackathon Starter&lt;/strong&gt; is a popular Node.js boilerplate that integrates various third-party APIs and services.&lt;br&gt;&lt;br&gt;
Its &lt;strong&gt;Google Maps example&lt;/strong&gt; demonstrates how to embed an interactive map in a webpage with features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom markers
&lt;/li&gt;
&lt;li&gt;Font Awesome icons integration
&lt;/li&gt;
&lt;li&gt;Info windows
&lt;/li&gt;
&lt;li&gt;Map controls
&lt;/li&gt;
&lt;li&gt;Boundary restrictions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of &lt;a href="https://github.com/sahat/hackathon-starter/issues/1428" rel="noopener noreferrer"&gt;Issue #1428&lt;/a&gt; was to implement &lt;strong&gt;comprehensive E2E test coverage&lt;/strong&gt; for this page.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 Technical Exploration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Initial Analysis and Tool Selection
&lt;/h3&gt;

&lt;p&gt;I began by analyzing the project’s existing test setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test Framework:&lt;/strong&gt; Playwright (already configured)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment setup:&lt;/strong&gt; Dual &lt;code&gt;.env&lt;/code&gt; configuration (&lt;code&gt;.env&lt;/code&gt; vs &lt;code&gt;test/.env.test&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target page:&lt;/strong&gt; &lt;code&gt;/api/google-maps&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Playwright?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Powerful browser automation
&lt;/li&gt;
&lt;li&gt;Rich element locator options
&lt;/li&gt;
&lt;li&gt;Network request interception
&lt;/li&gt;
&lt;li&gt;Cross-browser support
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  The First Major Discovery — &lt;code&gt;window.map.getCenter()&lt;/code&gt; Problem
&lt;/h3&gt;

&lt;p&gt;At first, I tried using &lt;code&gt;window.map.getCenter()&lt;/code&gt; to verify the map’s center position.&lt;br&gt;&lt;br&gt;
However, it didn’t work as expected. After inspecting the source code, I found that the &lt;code&gt;map&lt;/code&gt; object wasn’t accessible globally — meaning the test couldn’t directly call Google Maps API methods.&lt;/p&gt;

&lt;p&gt;This discovery made me realize that &lt;strong&gt;many standard map testing approaches wouldn’t apply&lt;/strong&gt; in this implementation.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧪 Testing Strategy
&lt;/h2&gt;

&lt;p&gt;Faced with limited API access, I designed a &lt;strong&gt;multi-layered testing strategy&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DOM-level validation&lt;/strong&gt; – verify key elements and containers
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Script validation&lt;/strong&gt; – confirm Google Maps API is correctly loaded
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Map tile detection&lt;/strong&gt; – ensure the map visually loads
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom marker testing&lt;/strong&gt; – verify custom markers and info windows
&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  🚫 The Challenge of Error Handling Tests
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Simulating API Key Failure
&lt;/h3&gt;

&lt;p&gt;At first, I almost overlooked the scenario where the app might fail to connect to the Google Maps API — because after setting up the environment, the connection always worked smoothly.  &lt;/p&gt;

&lt;p&gt;It wasn’t until one day, during a random network interruption, that I accidentally discovered the app had a &lt;strong&gt;built-in mechanism&lt;/strong&gt; for handling API connection failures. That unexpected finding reminded me how easy it is to miss edge cases when everything “just works.”&lt;/p&gt;

&lt;p&gt;To validate this behavior, I used Playwright’s &lt;strong&gt;request interception&lt;/strong&gt; feature to simulate a failed API request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/maps/api/js*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Complete Error Verification Matters
&lt;/h3&gt;

&lt;p&gt;Initially, I only checked either the error title or message.&lt;br&gt;&lt;br&gt;
Later, I realized that &lt;strong&gt;complete error validation&lt;/strong&gt; should check &lt;em&gt;both&lt;/em&gt; — ensuring the app gracefully handles and communicates failures to users.&lt;/p&gt;

&lt;p&gt;This experience taught me that covering as many runtime scenarios as possible in testing — even rare or “unlikely” ones — often reveals hidden robustness (or fragility) in the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎛️ The Center Map Button Dilemma
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;“Center Map” button&lt;/strong&gt; turned out to be the most challenging test item.&lt;br&gt;&lt;br&gt;
Although the implementation worked correctly in the UI, the test couldn’t verify its effect because the &lt;code&gt;map&lt;/code&gt; variable wasn’t globally exposed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current Testing Limitations
&lt;/h3&gt;

&lt;p&gt;✅ Button existence&lt;br&gt;&lt;br&gt;
✅ Button visibility&lt;br&gt;&lt;br&gt;
❌ Unable to verify recentering behavior  &lt;/p&gt;

&lt;h3&gt;
  
  
  Proposed Solutions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modify source code to include &lt;code&gt;window.map = map&lt;/code&gt; (global reference)
&lt;/li&gt;
&lt;li&gt;Alternative check: monitor map tile or CSS transform changes
&lt;/li&gt;
&lt;li&gt;Visual regression: compare before/after screenshots
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📊 Final Test Results
&lt;/h2&gt;

&lt;p&gt;After multiple iterations and optimizations, I implemented &lt;strong&gt;7 comprehensive test cases&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Category&lt;/th&gt;
&lt;th&gt;Coverage&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page Load &amp;amp; Element Display&lt;/td&gt;
&lt;td&gt;DOM validation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Maps JS API Load&lt;/td&gt;
&lt;td&gt;Script validation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map Initialization &amp;amp; Custom Elements&lt;/td&gt;
&lt;td&gt;Functional verification&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Error Handling&lt;/td&gt;
&lt;td&gt;Failure scenario simulation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map Controls &amp;amp; Interactions&lt;/td&gt;
&lt;td&gt;UI interaction testing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Font Awesome Icons &amp;amp; Marker Position&lt;/td&gt;
&lt;td&gt;Visual check&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marker Click &amp;amp; Info Window&lt;/td&gt;
&lt;td&gt;Content verification&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Coverage Highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Web fundamentals&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🗺️ &lt;strong&gt;Map API integration&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🚨 &lt;strong&gt;Error handling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🖱️ &lt;strong&gt;User interactions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Visual consistency&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎓 Key Learnings and Reflections
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Technical Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mastered Playwright&lt;/strong&gt;: Advanced usage of element locators, network interception, and JS evaluation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Integration Testing&lt;/strong&gt;: Learned alternative strategies when direct API access isn’t possible.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling&lt;/strong&gt;: Realized the importance of verifying complete error content.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project Management Insights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task Decomposition&lt;/strong&gt;: Broke down complex testing goals into smaller, achievable units.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterative Improvement&lt;/strong&gt;: Started with basic tests and gradually expanded coverage.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear Communication&lt;/strong&gt;: Documented limitations and proposed solutions clearly in GitHub issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Open Source Experience
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Understanding the Codebase&lt;/strong&gt;: Deeply reading existing implementation is crucial.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respecting Original Design&lt;/strong&gt;: Extend coverage without disrupting functionality.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constructive Contribution&lt;/strong&gt;: Don’t just point out problems — propose practical solutions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔮 Future Outlook
&lt;/h2&gt;

&lt;p&gt;This experience gave me a deeper understanding of E2E testing. In future projects, I plan to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perform &lt;strong&gt;testability analysis&lt;/strong&gt; before implementation
&lt;/li&gt;
&lt;li&gt;Document &lt;strong&gt;testing strategy rationale&lt;/strong&gt; and known limitations
&lt;/li&gt;
&lt;li&gt;Continuously &lt;strong&gt;monitor and improve test coverage&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Conclusion
&lt;/h2&gt;

&lt;p&gt;What started as a “simple Google Maps test” turned into a comprehensive testing journey covering &lt;strong&gt;API integration, error handling, and user interaction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This process not only strengthened my technical skills but also deepened my appreciation for the open-source community.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every technical limitation can be an opportunity for innovation.&lt;br&gt;&lt;br&gt;
Every debugging session can lead to meaningful learning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re interested in this topic, feel free to check out my contribution on GitHub:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PR:&lt;/strong&gt; &lt;a href="https://github.com/sahat/hackathon-starter/pull/1457" rel="noopener noreferrer"&gt;#1457&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue:&lt;/strong&gt; &lt;a href="https://github.com/sahat/hackathon-starter/issues/1428" rel="noopener noreferrer"&gt;#1428 – Add E2E tests for Google Maps integration example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>e2etest</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Reflections on Designing a Search Autocomplete System</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Sun, 05 Oct 2025 06:57:15 +0000</pubDate>
      <link>https://dev.to/andersontsai/reflections-on-designing-a-search-autocomplete-system-2j87</link>
      <guid>https://dev.to/andersontsai/reflections-on-designing-a-search-autocomplete-system-2j87</guid>
      <description>&lt;p&gt;This week in our Toronto Study Group meeting, I shared Chapter 13 of "System Design Interview", which focuses on designing a search autocomplete system (like Google’s typeahead).&lt;/p&gt;

&lt;p&gt;Instead of summarizing the whole chapter (you can see our &lt;a href="https://torontostudygroup.github.io/study-notes/notes/system-design-interview/ch13" rel="noopener noreferrer"&gt;study notes here&lt;/a&gt;), I want to highlight my personal takeaways.&lt;/p&gt;




&lt;h2&gt;
  
  
  Learning About Trie
&lt;/h2&gt;

&lt;p&gt;Before this, I only had a very basic understanding of the Trie data structure. This chapter gave me a clearer picture of why it’s so often mentioned in system design.&lt;/p&gt;

&lt;p&gt;What stood out to me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast prefix lookups&lt;/strong&gt;: a Trie lets you quickly jump down character by character until you reach the prefix node. It doesn’t matter if there are millions of queries stored — the lookup only depends on the length of the prefix.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching the top-k results&lt;/strong&gt;: instead of searching the whole subtree every time, each node can keep a small list of the most popular queries. This uses more memory, but it makes the response feel instant to the user.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A simple idea, but powerful in practice&lt;/strong&gt;: seeing how these small optimizations change a basic data structure into the backbone of something like Google autocomplete was eye-opening. It made me realize that system design isn’t about inventing new structures, but about applying and adapting classic ones to meet scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though I haven’t implemented a full Trie-based system myself, I now understand better how it connects to real-world needs: speed, caching, and user experience at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  System Design Insights
&lt;/h2&gt;

&lt;p&gt;Over the past few weeks of reading about scalable system design, my mental model has shifted.&lt;/p&gt;

&lt;p&gt;In the past, I used to think in simple terms: a frontend, a server, and a database — and that felt enough. But now I see how much more there is when you operate at massive scale.&lt;/p&gt;

&lt;p&gt;Concepts like load balancers, shard managers, or even command queues are still a bit abstract to me. Sometimes I even ask myself: “Why not just one server to handle it all?”&lt;/p&gt;

&lt;p&gt;But when I imagine systems serving millions of users, it becomes clear that a single server would never be enough. These architectural pieces — though complex — are the reason why large-scale systems can stay fast, reliable, and resilient.&lt;/p&gt;




&lt;h2&gt;
  
  
  Extra Reflections from Our Discussion
&lt;/h2&gt;

&lt;p&gt;One thing I found fascinating: &lt;strong&gt;Google really does send a query for every single character you type&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It feels so seamless that you don’t even notice — but behind the scenes, that must be billions of requests.  &lt;/p&gt;

&lt;p&gt;We also talked about whether techniques like &lt;strong&gt;debouncing&lt;/strong&gt; are used to reduce the server load. Maybe Google applies it, maybe not — but from the user’s perspective, it feels instant. That balance between user experience and server cost is really interesting.  &lt;/p&gt;

&lt;p&gt;Another fun idea we explored was the use of &lt;strong&gt;Main Trie + Side Trie&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main Trie&lt;/strong&gt;: stable, historical data
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Side Trie&lt;/strong&gt;: recent or trending queries
Merging them ensures autocomplete feels both reliable &lt;em&gt;and&lt;/em&gt; fresh. This kind of layered indexing was new to me and gave me a better appreciation for search system design.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;Right now, all of this is still a bit abstract since I haven’t built something at this scale.&lt;br&gt;&lt;br&gt;
But I see these patterns as &lt;strong&gt;mental models&lt;/strong&gt; I can draw on in the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If I ever need to design a program that scales, I’ll know to think about &lt;strong&gt;indexing strategies, cache design, and data aggregation pipelines&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Even just learning about Trie reminded me that “classic” data structures can directly influence how real-world systems are built.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;This was part of our &lt;strong&gt;Toronto Study Group’s weekly sharing&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I’m grateful for the chance to not only read but also &lt;strong&gt;explain my understanding&lt;/strong&gt;, which helps me internalize the ideas better.&lt;/p&gt;

&lt;p&gt;For anyone learning system design:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It’s okay if it feels abstract now. These concepts are seeds — they’ll grow into real tools once you face scaling challenges in practice.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>systemdesign</category>
      <category>scalability</category>
      <category>learning</category>
      <category>toronto</category>
    </item>
    <item>
      <title>I’m Joining Hacktoberfest 2025</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Mon, 29 Sep 2025 05:56:11 +0000</pubDate>
      <link>https://dev.to/andersontsai/im-joining-hacktoberfest-2025-5d29</link>
      <guid>https://dev.to/andersontsai/im-joining-hacktoberfest-2025-5d29</guid>
      <description>&lt;p&gt;A few days ago, I decided to take part in Hacktoberfest 2025&lt;br&gt;
! &lt;a href="https://hacktoberfest.com/" rel="noopener noreferrer"&gt;https://hacktoberfest.com/&lt;/a&gt;&lt;br&gt;
Honestly, I’m both excited and confused — can I really push meaningful PRs? I have no idea. But that’s the beauty of Hacktoberfest: it’s about trying, learning, and finding a place where I can contribute.&lt;/p&gt;

&lt;p&gt;In this post, I’ll briefly introduce what Hacktoberfest is, how the rules work, and share my current thoughts and hopes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Hacktoberfest?
&lt;/h3&gt;

&lt;p&gt;Hacktoberfest is an annual, month-long celebration of open source software. It’s supported by DigitalOcean, Major League Hacking, and other partners. The goal is simple but powerful:&lt;/p&gt;

&lt;p&gt;Encourage more people to get involved in open source.&lt;br&gt;
Grow the community by lowering the barrier to entry.&lt;br&gt;
Reward contributors for their efforts.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Join
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Register: Sign up on hacktoberfest.com with your GitHub (or GitLab) account.&lt;/li&gt;
&lt;li&gt;Find projects: Look for repositories that have the hacktoberfest topic or issues labeled as “good first issue” / “help wanted.”&lt;/li&gt;
&lt;li&gt;Make Pull Requests: During October, submit PRs to participating repositories. Contributions don’t need to be huge — fixing typos, improving docs, or adding small features all count.&lt;/li&gt;
&lt;li&gt;Reach the goal: Typically, 6 accepted PRs are required to complete Hacktoberfest (subject to the 2025 rules).&lt;/li&gt;
&lt;li&gt;Get rewards!!! &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  My Strategy
&lt;/h3&gt;

&lt;p&gt;To make the most out of Hacktoberfest 2025, here’s my plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prepare now: practice Git/GitHub workflows, and warm up with small contributions.&lt;/li&gt;
&lt;li&gt;Find interesting projects: look for ones related to technologies I use or topics I care about.&lt;/li&gt;
&lt;li&gt;Document the journey: I’ll write about my attempts, successes, and even failures. I hope writing blogs can be a way to push myself, haha&lt;/li&gt;
&lt;li&gt;Join the community hopefully: I have joined the Hacktoberfest Discord group. I found that there are some interesting repos there, and hopefully, I can find some repos and people I can work with.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Hacktoberfest 2025 feels like a big challenge for me. I don’t know yet if I’ll succeed, but I do know this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every attempt is a learning experience.&lt;/li&gt;
&lt;li&gt;Rejected PRs aren’t failures, they’re feedback.&lt;/li&gt;
&lt;li&gt;The important thing is to try, explore, and connect with the community.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So here I go — diving into Hacktoberfest, hoping to discover cool projects, contribute in meaningful ways, and enjoy the journey.&lt;/p&gt;

&lt;p&gt;If you’re also joining Hacktoberfest, let’s connect and encourage each other along the way!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Release 0.1 - Go?</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Sat, 13 Sep 2025 08:01:20 +0000</pubDate>
      <link>https://dev.to/andersontsai/release-01-go-1ijj</link>
      <guid>https://dev.to/andersontsai/release-01-go-1ijj</guid>
      <description>&lt;p&gt;In OSD600 2025 Summer, Release is the project we will spend most of our time on. It is a CLI tool that can generate a text file for a repo, so we can send it to an LLM. This way, it preserves not only the content of the files but also the structure of the repo.&lt;/p&gt;

&lt;p&gt;The first thing I need to decide is which language I would like to use.&lt;/p&gt;

&lt;p&gt;So far, I’ve given myself a challenge—Go might be a good choice.&lt;/p&gt;

&lt;p&gt;The first thing I considered is that I would like the user not to worry about the environment. They should just open the command line, type the command, run it, and get the result. I don’t want them to have to install any unnecessary software.&lt;br&gt;
→ That’s why C++ might also be a good choice.&lt;/p&gt;

&lt;p&gt;However, ChatGPT gave me another idea: how about Go?&lt;/p&gt;

&lt;p&gt;Go can also compile code into an .exe file, so people can use it directly. Also, I am eager to learn backend knowledge, and Go is one of the languages I would like to explore.&lt;/p&gt;

&lt;p&gt;So, that’s the story so far.&lt;/p&gt;

&lt;p&gt;I installed Go and finished my first tiny program hello-go, and started learning how to write in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, Go + VS Code!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah, just my first try.&lt;br&gt;
I guess I need some practice before I really start writing Release, and I hope I can push myself to do more.&lt;/p&gt;

&lt;p&gt;See you next time~&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Starting My Open Source Journey</title>
      <dc:creator>Anderson Yu-Hong Cai</dc:creator>
      <pubDate>Fri, 05 Sep 2025 06:22:13 +0000</pubDate>
      <link>https://dev.to/andersontsai/starting-my-open-source-journey-4hda</link>
      <guid>https://dev.to/andersontsai/starting-my-open-source-journey-4hda</guid>
      <description>&lt;p&gt;This post marks the beginning of my open source journey. If I am lucky, I may become involved in OSD600 at Seneca, which could make this path even more possible. But either way, I feel it is time to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who am I?
&lt;/h2&gt;

&lt;p&gt;I’m Anderson, someone who is always eager to explore new worlds—especially the ones that aren’t easy. That’s why, when I worked in finance, I studied Financial Engineering. I became a data analyst even before I officially held the title. Now, I am working hard to become a developer.&lt;/p&gt;

&lt;p&gt;That is the reason I am here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open source?
&lt;/h2&gt;

&lt;p&gt;Open source has always felt intimidating to me. Even now, I hesitate to dive in. Every time I research repositories, it seems like everyone is doing something cutting-edge, and I often feel lost.&lt;/p&gt;

&lt;p&gt;To me, open source is a milestone—a sign that you are becoming a real developer. That’s why I want to understand how to get involved. I want to know what it really is. I want to see the world from that perspective.&lt;/p&gt;

&lt;p&gt;I know I will need guidance. It’s like trying to climb the highest mountain: you must walk on your own, but without learning from others, you will either give up or fail. The journey requires both independence and support, and I don’t want to face it unprepared.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would like to get
&lt;/h2&gt;

&lt;p&gt;So far, I am not familiar with open source—the environment, the way people collaborate, the culture, the community news. I want to build a closer connection with it. That is the first thing I hope to achieve this term.&lt;/p&gt;

&lt;p&gt;The second thing I want to discover is: what can I do for the community? Can I contribute something? How do I find the right tasks and actually make a contribution?&lt;/p&gt;

&lt;p&gt;And finally, I want to explore who I can become through this journey. Up to now, I’ve been learning many things, but I haven’t decided where to go deeper. What am I good at? What do I truly enjoy? What does the community need? I need to find these answers so I can focus, go deeper, and eventually find my own way.&lt;/p&gt;

&lt;p&gt;Open source has always been on my mind, and I believe this is the right time to begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search for the repo trend
&lt;/h2&gt;

&lt;p&gt;Deciding which repo to introduce is really difficult. I found one repo that tries to build an AI-oriented quantitative investment platform, which matches my financial background. I also saw projects aiming to build AI agents, which is a popular topic nowadays. But finally, I chose the one below, which attracted me the most.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/microsoft/PowerToys" rel="noopener noreferrer"&gt;PowerToys&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;PowerToys is a Windows system utilities project that includes many interesting tools like Color Picker, FancyZones, Text Extractor, and other cool small utilities. It also has a long history.(&lt;a href="https://en.wikipedia.org/wiki/Microsoft_PowerToys" rel="noopener noreferrer"&gt;Wiki - Microsoft PowerToys&lt;/a&gt;)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd09sbggb4z8se76cm3h0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd09sbggb4z8se76cm3h0.png" alt="Current utilities in PowerToys" width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the reasons I chose this repo is because the project is written in C# and C++. After learning a lot of C++, I wanted to find a place where I could actually use it. Also, these tools are really cool. Snipping Tool is the one I use the most, and I was so excited when I discovered that it originally came from PowerToys(&lt;a href="https://en.wikipedia.org/wiki/Snipping_Tool" rel="noopener noreferrer"&gt;Wiki - Snipping Tool&lt;/a&gt;). I guess this shows how open source can improve the world.&lt;/p&gt;




&lt;p&gt;So, this is my first blog, and I hope it gives a brief idea of who I am, what I am doing, and what I have explored so far. Even though it’s just a tiny step, it might turn out to be an important one for me.&lt;/p&gt;

&lt;p&gt;You don’t have to be great to start, but you have to start to become great. Let’s keep going together!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>senecaosd600</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
