[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"categories":3,"posts::hacks:2:6:":86,"$fmAbo7HX1697lOJ4AVNBJl1PR7wUF0IkR_62krtbwQAE":200},{"data":4,"meta":83},[5,13,21,33,41,49,61,73],{"_id":6,"name":7,"createdAt":8,"updatedAt":9,"uuid":10,"description":11,"slug":12},"63c8a819ebd5da50564b61e1","Season","Thu Jan 19 2023 10:16:57 GMT+0800 (Singapore Standard Time)","Sun Nov 19 2023 10:26:28 GMT+0800 (Singapore Standard Time)","f320644a-3083-41c0-84cb-0d3fa5551f9c","Seasonal Symphony: Wishes and Whispers Throughout the Year.","season",{"_id":14,"name":15,"createdAt":16,"updatedAt":17,"uuid":18,"description":19,"slug":20},"63c8e274ebd5da50564b61e5","Books","Thu Jan 19 2023 14:25:56 GMT+0800 (Singapore Standard Time)","Sun Nov 19 2023 10:34:33 GMT+0800 (Singapore Standard Time)","cd14b16a-42b5-42d6-8d77-5c462a4d0f0f","TechTomes: Unveiling Insights from My Reading List.","books",{"_id":22,"name":23,"createdAt":24,"updatedAt":25,"uuid":26,"description":27,"slug":28,"image":29,"imageAlt":30,"metaDescription":31,"metaTitle":32},"63c8e27febd5da50564b61e6","Fun","Thu Jan 19 2023 14:26:07 GMT+0800 (Singapore Standard Time)","Fri Sep 04 2026 12:00:52 GMT+0800 (Singapore Standard Time)","a21f9898-e840-4a66-bf53-d559fbecd8a2","Not everything needs to be about work, strategy or the latest technological disruption. Fun is where I keep the side quests: travel, photography, drone flying, unusual experiences and stories that refuse to behave like serious professional content. The CTO Show may occasionally wander in too - it has never been especially good at respecting boundaries.","fun","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnewsfun.jpg","Flying drone!","Travel, photography, drone flying and other side quests beyond the usual workday—plus stories that simply refuse to fit anywhere else.","Fun: Travel, Photography, Drones & Side Quests",{"_id":34,"name":35,"createdAt":36,"updatedAt":37,"uuid":38,"description":39,"slug":40},"63c8e283ebd5da50564b61e7","Hacks","Thu Jan 19 2023 14:26:11 GMT+0800 (Singapore Standard Time)","Sun Nov 19 2023 10:36:02 GMT+0800 (Singapore Standard Time)","799564dd-7b72-46c5-a45e-5de9b03562df","Life tips not only for geeks. ","hacks",{"_id":42,"name":43,"createdAt":44,"updatedAt":45,"uuid":46,"description":47,"slug":48},"63ddb29077ed51d12c4d2369","Thought","Sat Feb 04 2023 09:19:12 GMT+0800 (Singapore Standard Time)","Sun Nov 19 2023 10:32:11 GMT+0800 (Singapore Standard Time)","ce03e1f7-4ccf-4f31-bf12-a6890e7ab2e2","In the Stream of Consciousness: Everyday Thoughts.","thought",{"_id":50,"name":51,"createdAt":52,"updatedAt":53,"uuid":54,"description":55,"slug":56,"image":57,"imageAlt":58,"metaDescription":59,"metaTitle":60},"63e8bb2053fe24ed2c17b632","Side Project","Sun Feb 12 2023 18:10:40 GMT+0800 (Singapore Standard Time)","Fri Sep 04 2026 12:08:52 GMT+0800 (Singapore Standard Time)","3affba79-dabc-486b-b387-88b111dd2ca9","The projects nobody assigned, nobody requested and nobody promised would actually work. This is where I document electronics, prototypes, experiments and ideas built mostly from curiosity plus the mistakes, unexpected detours and occasional small victories that happen somewhere between “what if?” and “why is that smoking?”","side-project","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnewsside-projects.jpg","Michal's lab","Electronics, prototypes and curious experiments from promising ideas to useful mistakes and the occasional project that actually works.","Side Projects: Experiments, Builds & Useful Mistakes",{"_id":62,"name":63,"createdAt":64,"updatedAt":65,"uuid":66,"description":67,"slug":68,"image":69,"imageAlt":70,"metaDescription":71,"metaTitle":72},"64a60fa6d6a64c035ffff733","Articles","Thu Jul 06 2023 08:49:42 GMT+0800 (Singapore Standard Time)","Fri Sep 04 2026 10:57:46 GMT+0800 (Singapore Standard Time)","81e1b46d-752b-4cce-92fc-756abf9b0f05","A collection of stories, observations and ideas that deserve more room than a quick update. From technology and business to places, trends and everyday curiosities explored with a personal perspective, practical context and no unnecessary seriousness.","articles","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnewsarticles.jpg","work-and-careers","Stories and observations about technology, business, places and everyday curiosities—explored with practical context and a personal perspective.","Articles: Stories, Ideas & Everyday Observations",{"_id":74,"name":75,"description":76,"image":77,"imageAlt":70,"slug":70,"createdAt":78,"updatedAt":79,"uuid":80,"metaDescription":81,"metaTitle":82},"6a9a0dfb49e7c42d005c01bb","Work & Careers","Work is changing, careers are getting less predictable, and the old advice does not always survive contact with reality. This section explores job markets, hiring trends, workplace culture and the practical decisions that shape our professional lives with curiosity, personal perspective and the occasional raised eyebrow.","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnewswork.jpg","Fri Sep 04 2026 08:16:59 GMT+0800 (Singapore Standard Time)","Fri Sep 04 2026 10:45:32 GMT+0800 (Singapore Standard Time)","2466fa42-adb8-450d-95ca-ac0324120844","Practical takes on job markets, career growth, hiring trends and workplace culture plus the occasional uncomfortable truth about working life.","Work & Careers: Jobs, Growth & Workplace Trends",{"totalnoOfItems":84,"perPage":85,"noOfItemsOnCurrentPage":84},8,24,{"data":87,"meta":197},[88,108,126,144,161,180],{"relatedTools":89,"_id":90,"id":91,"title":92,"alt":93,"category":35,"date":94,"author":95,"readTime":96,"content":97,"image":98,"more":99,"extendedContent":100,"asHTML":99,"headTitle":101,"metaDesc":102,"photoCredit":95,"createdAt":103,"updatedAt":104,"uuid":105,"categorySlug":40,"tags":106},[],"6562a53411cb0a02ccb397d4","still-using-browser-as-default-browser","Still using browser as \"default browser\"?","Screenshot of Velja app.","2023-11-26T01:21:00.000Z","Michal",2,"When managing multiple browsers on your device, it's advisable not to set a default browser. Instead, consider leveraging specialized apps that automate the process of opening links in your preferred browser. These apps can seamlessly handle link management or prompt you to choose the browser that suits your needs for each link.","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fvelja.jpg","true","\u003Ch2>Browser automation for easy web surfing.\u003C\u002Fh2>\n\u003Cp>Let's delve into a simple use case. I maintain two accounts on an error tracing tool—one for work and the other for my current personal project (which you're currently exploring). To manage these, I use both Chrome and Safari simultaneously. When I receive an email notification regarding an issue, I want a seamless experience where clicking the link directs me to the right account without any hassle. This is achievable by utilizing an application that works its magic in the background.\u003C\u002Fp>\n\u003Cp>Fortunately, there's a variety of apps available today that offer this convenient feature. Personally, for Mac users, my top recommendation is \u003Ca href=\"https:\u002F\u002Fsindresorhus.com\u002Fvelja\" target=\"_blank\" rel=\"noopener\">Velja\u003C\u002Fa> (about my previous choice - \u003Ca href=\"\u002Fpost\u002Fchange-your-default-browser\">Finicky, you can read in this post\u003C\u002Fa>). This tool allows for a user-friendly setup of rules, enabling you to effortlessly manage which browser opens your links. \u003Cp> \n\u003Cimg src=\"https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fvelja-rules.jpg\" alt=\"Velja rules screenshot\">\n\u003Cp>Additionally, you have the option to set a 'prompt' as the default choice. This means that each time you click a link, a prompt will appear, allowing you to manually select the preferred browser.\u003C\u002Fp>\n\u003Cimg src=\"https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fvelja-prompt.jpg\" alt=\"Velja prompt screenshot\">\n\u003Cp>Notably, this app is not only stable but also conveniently \u003Ca href=\"https:\u002F\u002Fapps.apple.com\u002Fus\u002Fapp\u002Fvelja\u002Fid1607635845?mt=12\">available on the App Store\u003C\u002Fa>, and surprisingly, it's free of charge. While it won't cost you a dime to enhance your browsing experience, I highly recommend considering a small donation to the app's author, Sindre Sorhus, as a token of appreciation for their valuable contribution.\u003C\u002Fp>","Why you should Velja as default browser.","Manage multiple browsers without a default: use apps to automate link opening, and choose the browser that fits your needs for each link. ","Sun Nov 26 2023 09:53:56 GMT+0800 (Singapore Standard Time)","Fri Dec 08 2023 09:53:52 GMT+0800 (Singapore Standard Time)","f1a0debb-e182-4f70-9a71-a05525ec2031",[107],"App Review",{"relatedTools":109,"_id":110,"id":111,"title":112,"alt":113,"category":35,"date":114,"author":95,"readTime":96,"content":115,"image":116,"more":99,"extendedContent":117,"asHTML":99,"headTitle":118,"metaDesc":119,"draft":120,"photoCredit":95,"createdAt":121,"updatedAt":122,"uuid":123,"categorySlug":40,"tags":124},[],"654af2e8e39e4e02d1a13efe","desktop-2023-an-evolution-of-two-and-a-half-years","Desktop 2023: An Evolution of Two and a Half Years.","My desk in 2023","2023-11-08T02:18:00.000Z","Two and a half years ago, I shared my initial desk setup on this site (yeah, first post), accompanied by a few thoughts on the significance of customising your workspace to fit your specific requirements. Since then, my desk has undergone a remarkable transformation, with each change serving as a testament to the power of continuous improvement. ","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fdesk2023.jpg","\u003Ch2>Small, thoughtful adjustments.\u003C\u002Fh2>\u003Cp>The desk is a reflection of my evolving needs and a testament to the idea that small, thoughtful adjustments can make a world of difference. It's a blend of function, aesthetics, and personal creativity, and I'm excited to share how it has become a space that both inspires and enhances productivity.\u003C\u002Fp>\n\u003Cp>My current desk setup not only boasts the best components I could find but also features an immersive RGB ambient lighting system, meticulously crafted with an Arduino microcontroller and a custom 3D-printed casing, designed by yours truly.\u003C\u002Fp>\n\u003Cp>If you're interested how the light controller works, \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmsatbsx\u002Farduino-puck-lighting\" target=\"_new\">here\u003C\u002Fa> is a public version of my repo that evaluated into solution used in this setup. When other duties allow, I'll clean up and share publicly the final one (including screen tone colour grab for Mac).\u003C\u002Fp>\n\u003Cp class=\"text-center mt-3\">Ambient light: \u003Cimg class=\"max-w-md mx-auto rounded-lg\" src=\"https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Flight.jpg\" alt=\"ambient light with 3D printed housing\">\u003C\u002Fp>\n\u003Cp class=\"text-center mt-3\">Here is the \u003Ca href=\"https:\u002F\u002Fnews.michalspace.com\u002Fpost\u002Fmake-your-desk-really-yours.\">old one\u003C\u002Fa>: \u003Cimg class=\"max-w-md mx-auto rounded-lg\"  src=\"https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fmy_desk.jpg\" alt=\"my old desk\">\u003C\u002Fp>\n","My desk setup evolution. ","My desk has been an ever-evolving work of art, each change a reminder of the power of continuous improvement. Follow my journey to learn how I've made it.","false","Wed Nov 08 2023 10:31:04 GMT+0800 (Singapore Standard Time)","Mon Dec 04 2023 19:39:41 GMT+0800 (Singapore Standard Time)","d8feba9f-4287-4134-8325-0ffc160575a0",[125],"DIY",{"relatedTools":127,"_id":128,"id":129,"title":130,"alt":131,"category":35,"date":132,"author":95,"readTime":133,"content":134,"image":135,"more":99,"extendedContent":136,"asHTML":99,"headTitle":137,"metaDesc":138,"photoCredit":139,"createdAt":140,"updatedAt":141,"uuid":142,"categorySlug":40,"tags":143},[],"645f3a536fea6f03638c24b9","django-project-shipped-as-docker-image","Ship Django project as Docker image.","Shipping containers.","2023-05-13T07:18:00.000Z",4,"Recently I needed to deploy inherited Django project. My usual approach would be to ship it as docker container. Since python is not exactly my thing, I googled how to. Unfortunately there was no simple and clean tutorial. So I wrote it (with Gunincorn and Nginx to be production ready).","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fshipping-containers.jpg","\u003Ch2 class=\"text-2xl font-bold tracking-tight text-gray-900 mt-3\">Let's ship a Django project as a Docker image.\u003C\u002Fh2>\nA couple of prerequisites before we start:\u003Cbr>\n- docker installed and running on your machine,\u003Cbr>\n- since my tutorial is minimalistic, it is addressed to people with some experience.\u003Cbr>\u003Cbr>\nYou can begin with existing code, or create a new Django project:\n\u003Cpre class=\"terminal\">\ndjango-admin startproject dockerdjango\n\u003C\u002Fpre>\nIn my case file structure looks like this (before adding docker related code):\n\u003Cpre class=\"filelist\">\ndockerdjango\n├─appsample \n│ └...\n├─dockerdjango\n│ ├...\n│ ├settings.py\n│ ├urls.py\n│ ├views.py\n│ └wsgi.py\n├─static\n│ └...\n├─templates\n│ └...\n├─db.sglite3\n├─manage.py\n└─requirements.txt\n\u003C\u002Fpre>\nIn my approach, to build a Docker image we need 3 more files:\u003Cbr>\n1. \u003Cspan class=\"font-mono text-red-700\">\u002FDockerfile\u003C\u002Fspan> (\u002F represents root of your project next to manage.py)\n\u003Cpre>\nFROM python:3.11.3-slim-bullseye\n\n# install nginx\nRUN apt-get update && apt-get install nginx vim -y --no-install-recommends\nCOPY nginx.site.conf \u002Fetc\u002Fnginx\u002Fsites-available\u002Fdefault\nRUN ln -sf \u002Fdev\u002Fstdout \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log \\\n    && ln -sf \u002Fdev\u002Fstderr \u002Fvar\u002Flog\u002Fnginx\u002Ferror.log\n\n# copy source and install dependencies\nRUN mkdir -p \u002Fopt\u002Fapp\nRUN mkdir -p \u002Fopt\u002Fapp\u002Fpip_cache\nRUN mkdir -p \u002Fopt\u002Fapp\u002Fdockerdjango\nCOPY requirements.txt server-up.sh \u002Fopt\u002Fapp\u002F\nCOPY .pip_cache \u002Fopt\u002Fapp\u002Fpip_cache\u002F\nCOPY dockerdjango \u002Fopt\u002Fapp\u002Fdockerdjango\u002F\nCOPY appsample \u002Fopt\u002Fapp\u002Fappsample\u002F\nCOPY static \u002Fopt\u002Fapp\u002Fstatic\u002F\n# not default django templates folder (setup in settings.py) \nCOPY templates \u002Fopt\u002Fapp\u002Ftemplates\u002F\nWORKDIR \u002Fopt\u002Fapp\nRUN pip install -r requirements.txt --cache-dir \u002Fopt\u002Fapp\u002Fpip_cache\nRUN chown -R www-data:www-data \u002Fopt\u002Fapp\nRUN chmod 755 server-up.sh\n\n# start server\nEXPOSE 8020\nSTOPSIGNAL SIGTERM\nCMD [\"\u002Fopt\u002Fapp\u002Fserver-up.sh\"]\n\u003C\u002Fpre>\n2. \u003Cspan class=\"font-mono text-red-700\">\u002Fnginx.site.conf\u003C\u002Fspan>\n\u003Cpre>\n# nginx default site config for \u002Fetc\u002Fnginx\u002Fsites-available\u002Fdefault\n\nserver {\n    listen 8020;\n    server_name example.org;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8010;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n    location \u002Fstatic {\n        root \u002Fopt\u002Fapp;\n    }\n}\n\u003C\u002Fpre>\nand bash script to run it\u003Cbr>\n3. \u003Cspan class=\"font-mono text-red-700\">\u002Fserver-up.sh\u003C\u002Fspan>\n\u003Cpre>\n#!\u002Fusr\u002Fbin\u002Fenv bash\n# start-up.sh\n\n# Start Gunicorn processes & start the Nginx process and put it in the background\n(gunicorn dockerdjango.wsgi --user www-data --bind 0.0.0.0:8010 --workers 3) &\nnginx -g \"daemon off;\"\n\n# more on gunicon https:\u002F\u002Fdocs.gunicorn.org\u002Fen\u002Fstable\u002Fdeploy.html\n# more on nginx in container https:\u002F\u002Fdocs.nginx.com\u002Fnginx-management-suite\u002Fnim\u002Fprevious-versions\u002Fv1\u002Ftutorials\u002Fcontainers\u002F\n\u003C\u002Fpre>\nAnd a few updates to \u003Cspan class=\"font-mono text-red-700\">\u002Fdjangodocker\u002Fsettings.py\u003C\u002Fspan>\n\u003Cpre>\nALLOWED_HOSTS = ['*'] # not default\nSTATICFILES_DIRS = [  # not default\n    BASE_DIR \u002F \"static\",\n]\nCSRF_TRUSTED_ORIGINS = ['http:\u002F\u002F127.0.0.1:8020']  # not default\n\u003C\u002Fpre>\nYour \u003Cspan class=\"font-mono text-red-700\">\u002Frequirements.txt\u003C\u002Fspan> should contain at least:\n\u003Cpre>\ndjango == 4.2.1\ngunicorn == 20.1.0\n\u003C\u002Fpre>\nNow you're ready to build the image (type in terminal in root of your project where Dockerfile is located):\n\u003Cpre class=\"terminal\">\ndocker build -t yourfancytag .\n\u003C\u002Fpre>\nand run a container build out of the image:\n\u003Cpre class=\"terminal\">\ndocker run -it -p 8020:8020 --name dockerdjango yourfancytag\n\u003C\u002Fpre>\nYou should be able to access http:\u002F\u002F127.0.0.1:8020, in my project: \u002FGitHub link below\u002F\n\u003Cimg class=\"mx-auto w-10\u002F12 border my-5\" alt=\"Container ship\" src=\"https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fdockerdjango-safari.png\">\n\nLater you can fire it without interactive terminal (-it)\n\u003Cpre class=\"terminal\">\ndocker run dockerdjango\n\u003C\u002Fpre>\n\u003Chr class=\"mt-3\">\n\u003Ch3 class=\"text-2xl font-bold tracking-tight text-gray-900 mt-3\">Any issues?\u003C\u002Fh3>\nFirst check your Dockerfile, it happens you're trying to copy or run something that does not exist in your project. Audit static and templates folders, they are not default ones.\u003Cbr>\u003Cbr>\nStill failing? Compare with my project, it is published on Github: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmsatbsx\u002Fdockerdjango\">https:\u002F\u002Fgithub.com\u002Fmsatbsx\u002Fdockerdjango\u003C\u002Fa> or clone it (due to Cloudflare email obfuscation being unable to switch off in the line below please replace USER with git [at] github.com):\n\u003Cpre class=\"terminal\">\ngit clone USER:msatbsx\u002Fdockerdjango.git\n\u003C\u002Fpre>\nYou can also build from my image and explore (it can be pulled from hub.docker.com):\n\u003Cpre class=\"terminal\">\ndocker run -d -p 8020:8020 --name dd msatbsx\u002Fdockerdjango:1\n\u003C\u002Fpre>\nWhen the container is already created, you can run it interactive and explore inside:\n\u003Cpre class=\"terminal\">\ndocker exec -it dd bash\n\u003C\u002Fpre>","Django in Docker Image","Stuck on deploying a Django project? Check out this tutorial written by someone who had to figure it out too! #Django #Python #Tutorial","Unsplash","Sat May 13 2023 15:20:51 GMT+0800 (Singapore Standard Time)","Thu Dec 14 2023 08:32:40 GMT+0800 (Singapore Standard Time)","fd905ab7-f923-4f1c-b2e4-8bce3e849d69",[125],{"relatedTools":145,"_id":146,"id":147,"title":148,"alt":149,"category":35,"date":150,"author":95,"readTime":96,"content":151,"image":152,"more":99,"extendedContent":153,"asHTML":99,"headTitle":154,"metaDesc":155,"photoCredit":156,"createdAt":157,"updatedAt":158,"uuid":159,"categorySlug":40,"tags":160},[],"644a650a774c389bc4de01b8","change-your-default-browser","Change your default browser!","full screen browser on  laptop","2023-04-27T12:03:00.000Z","Are you a tech-savvy Mac user? Then you'll love this solution: change your default browser to an app that's not even a browser at all! Let me explain the problem: when you receive incoming messages with links, you want to be able to open them easily by clicking, but sometimes you'd like certain links to open in Chrome (like Google Meet) and others in Safari (like Medium.com). Read further to learn how to do this.","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Flaptop-browser.jpg","\u003Ch2>Setup is easy. At least for geeks ;)\u003C\u002Fh2>\nInstal Finicky App:\u003Cbr>\n\u003Cpre>\nbrew install --cask finicky\n\u003C\u002Fpre>\ncreate your configuration file at ~\u002F.finicky.js\u003Cbr>\nbelow you have my first experiments. \n\u003Cpre>\nmodule.exports = {\n  defaultBrowser: \"Safari\",\n\n  handlers: [\n    {\n      match: [\n        \"apple.com*\", \n        finicky.matchDomains(\u002F.*\\.apple.com\u002F)\n      ],\n      browser: \"Safari\"\n    },\n    {\n      match: [\n        \"google.com*\", \n        finicky.matchDomains(\u002F.*\\.google.com\u002F)\n      ],\n      browser: \"Brave Browser\"\n    },\n    {\n      match: [\n        \"atlassian.net\u002F*\", \n        \"*.atlassian.net\u002F*\", \u002F\u002F match subdomains\n      ],\n      browser: \"Google Chrome\"\n    }\n    ,\n    {\n      match: [\n        \"miro.com\u002F*\",\n      ],\n      browser: \"Google Chrome\"\n    },\n    {\n      match: [\n        \"127.0.0.1\u002F*\"\n      ],\n      browser: \"Brave Browser\"\n    }\n  ]\n}\n\u003C\u002Fpre>\nLast part is set default browser to Finicky at System Settings > Desktop & Dock > Default web browser (in Ventura, older OSX version have a bit different places). \nDone. With the example below, you'll open local addresses in Brave, Google, Miro and Atlassian in Chrome, others in Safari. This is only the tip of an iceberg. It is JS, you can go way further with custom conditions!\u003Cbr>\nLearn more about Finicky \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjohnste\u002Ffinicky\" target=\"_new\">here\u003C\u002Fa>","Change your default browser to Finicky","Tech-savvy Mac users, learn how to open certain links in Chrome & others in Safari by changing your default browser. Not to a browser at all!","Unsplash\u002FMichal","Thu Apr 27 2023 20:05:30 GMT+0800 (Singapore Standard Time)","Mon Dec 04 2023 19:44:45 GMT+0800 (Singapore Standard Time)","cc6ce5f3-d805-4515-86e5-b77ef2be0cf4",[107],{"relatedTools":162,"_id":163,"id":164,"title":165,"alt":166,"category":35,"date":167,"author":95,"readTime":168,"content":169,"image":170,"more":99,"extendedContent":171,"asHTML":99,"headTitle":172,"metaDesc":173,"createdAt":174,"updatedAt":175,"uuid":176,"categorySlug":40,"tags":177},[],"64352530774c389bc4de01b2","end-to-end-testing-tool-done-right","Playwright, end to end testing tool done right.","Playwright website screenshoot","2023-04-11T09:14:00.000Z",1,"End-to-end testing is essential, especially when considering regression tests. All the platforms I've used in the past feel dated, as though I'm using Windows 95. Recently, while experimenting with Svelte, I came across Playwright. It's amazing! There's hardly any learning curve, and it's all integrated into my IDE. Give it a try - you won't regret it!","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fplaywright_small.png","\u003Ch2>Can be doing e2e tests easy? Possible with \u003Ca href=\"https:\u002F\u002Fplaywright.dev\" target=\"_blank\" rel=\"noopener\">Playwright.\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>End-to-end testing is an indispensable aspect of ensuring the robustness of software, particularly when it comes to executing regression tests. Traditionally, the platforms available for such testing have often felt outdated, reminiscent of an era long past. However, my recent exploration of Playwright has been nothing short of revelatory, especially as I dabbled with Svelte.\u003C\u002Fp>\n\u003Cp>The experience is nothing short of amazing! Unlike its counterparts, Playwright brings a refreshing modernity to the testing landscape. What sets it apart is not just its effectiveness but the seamless integration into my integrated development environment (IDE). The learning curve is remarkably gentle, making it accessible even for those new to the world of end-to-end testing. For anyone seeking an agile, contemporary solution for testing, I wholeheartedly recommend giving Playwright a try – the efficiency and user-friendly experience it brings to the table are truly game-changers in the realm of software testing. You won't regret making it a part of your testing toolkit!\u003C\u002Fp>","Playwright end to end tests","End-to-end testing made easy with Playwright: no learning curve, works with your IDE, and no more Windows 95 feels. Get it and thank me later!","Tue Apr 11 2023 17:15:28 GMT+0800 (Singapore Standard Time)","Mon Dec 04 2023 19:45:37 GMT+0800 (Singapore Standard Time)","8855a586-4d53-401e-b6f0-a47478becd65",[178,179],"Testing","TDD",{"relatedTools":181,"_id":182,"id":183,"title":184,"alt":185,"category":35,"date":186,"author":95,"readTime":96,"content":187,"image":188,"more":99,"extendedContent":189,"asHTML":99,"headTitle":190,"metaDesc":191,"photoCredit":95,"createdAt":192,"updatedAt":193,"uuid":194,"categorySlug":40,"tags":195},[],"64325dc5774c389bc4de01ad","understand-flex-box-in-minutes","Learn FlexBox in minutes.","Flex Box demo app screenshoot","2023-04-09T06:33:00.000Z","A few years ago, I conducted a session with individuals who were beginning their journey as front-end developers. It was quite surprising to me that they were having difficulty understanding FlexBox. To assist them, I created this demo using TailwindCSS classes - it might be of help to you too!","https:\u002F\u002Fmsatbsx.sgp1.digitaloceanspaces.com\u002Fnews\u002Fflex-box-demo-enhanced-center.jpg","\u003Ch2 class=\"text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl\">Try it!\u003C\u002Fh2>\nJust add a few boxes and play with radio buttons. \u003Cbr>\nBy clicking them you \u003Cspan class=\"font-semibold\">only change classes of the playground container div\u003C\u002Fspan> (with white background). Classes assigned to colourful boxes are never updated after they have been generated (random: background, width and height).\u003Cbr>\nIf you want to see under the hood, check it on \u003Ca href=\"https:\u002F\u002Fcodepen.io\u002Fmichalszymaniak\u002Fpen\u002FabWmdyQ\" rel=\"noopener\" style=\"color: rgb(14 165 233)\" class=\"font-semibold\" target=\"_new\">Codepen\u003Ca> or clone from \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmsatbsx\u002Flearn-flexbox-with-tailwindcss\" style=\"color: rgb(14 165 233)\" class=\"font-semibold\" target=\"_new\">Github\u003C\u002Fa>.\n\u003Cscript src=\"\u002Fflexbox-app.js\">\u003C\u002Fscript>\n\u003Cdiv id=\"wrapper\">\u003C\u002Fdiv>","Understand FlexBox","A few years ago I helped new front-end devs with their FlexBox struggles. Check out my TailwindCSS demo to help you too - it might be just what you need!","Sun Apr 09 2023 14:40:05 GMT+0800 (Singapore Standard Time)","Tue Dec 05 2023 15:38:28 GMT+0800 (Singapore Standard Time)","c4709b47-43b7-4b3f-9fed-12f33a9686f5",[196],"",{"totalnoOfPosts":198,"page":96,"perPage":199,"noOfPostOnCurrentPage":199},17,6,{"enabled":201},true]