<?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: Miguel Teheran</title>
    <description>The latest articles on DEV Community by Miguel Teheran (@mteheran).</description>
    <link>https://dev.to/mteheran</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%2F78871%2F230da1c3-ff2a-4c1f-bcb5-5db20458ae46.jpg</url>
      <title>DEV Community: Miguel Teheran</title>
      <link>https://dev.to/mteheran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mteheran"/>
    <language>en</language>
    <item>
      <title>New Tech Roles Created by the Rise of AI</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Mon, 06 Apr 2026 22:58:22 +0000</pubDate>
      <link>https://dev.to/mteheran/new-tech-roles-created-by-the-rise-of-ai-3362</link>
      <guid>https://dev.to/mteheran/new-tech-roles-created-by-the-rise-of-ai-3362</guid>
      <description>&lt;p&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%2F0v7riaa3klx476bwmxmo.webp" 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%2F0v7riaa3klx476bwmxmo.webp" alt="New AI tech roles" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Artificial intelligence has transformed many roles and responsibilities in the technology world. Since around 2010, we have seen data-related roles such as Data Analyst, Data Engineer, and Data Scientist. However, today the landscape goes far beyond analyzing data to build machine learning models.&lt;/p&gt;

&lt;p&gt;The widespread adoption of AI — and more importantly, how it is applied within software projects — has created entirely new job positions. These roles are built on strong programming foundations, but their daily activities are fundamentally different, centered around interacting with, orchestrating, and operationalizing artificial intelligence.&lt;/p&gt;

&lt;p&gt;Below are some of the emerging roles shaped by this new AI-driven era.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intelligence Engineer
&lt;/h3&gt;

&lt;h4&gt;
  
  
  (Applied AI Engineer)
&lt;/h4&gt;

&lt;p&gt;The Intelligence Engineer designs and integrates artificial intelligence capabilities into systems, digital products, and development processes. Their goal is to turn AI models into practical, scalable solutions that meet business needs by automating tasks, making decisions, and creating measurable value.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing architectures that integrate AI models (LLMs, ML models, external APIs).&lt;/li&gt;
&lt;li&gt;Building pipelines using RAG, embeddings, and vector databases.&lt;/li&gt;
&lt;li&gt;Designing and optimizing structured prompts.&lt;/li&gt;
&lt;li&gt;Orchestrating agents and autonomous workflows.&lt;/li&gt;
&lt;li&gt;Evaluating and improving the quality of AI-generated outputs.&lt;/li&gt;
&lt;li&gt;Implementing validations, metrics, and security controls.&lt;/li&gt;
&lt;li&gt;Optimizing cost, latency, and overall model performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agentic AI Expert
&lt;/h3&gt;

&lt;h4&gt;
  
  
  (Agent-Based AI Specialist)
&lt;/h4&gt;

&lt;p&gt;The Agentic AI Expert specializes in designing, implementing, and optimizing systems built around autonomous AI agents. Their focus is creating architectures where multiple agents perceive, reason, make decisions, and execute actions in coordination to solve complex problems and automate end-to-end processes.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing autonomous agents and agent-based systems.&lt;/li&gt;
&lt;li&gt;Defining planning, memory, and decision-making mechanisms.&lt;/li&gt;
&lt;li&gt;Implementing agents with access to tools, APIs, and databases.&lt;/li&gt;
&lt;li&gt;Orchestrating communication and coordination between agents.&lt;/li&gt;
&lt;li&gt;Evaluating agent performance, stability, and alignment.&lt;/li&gt;
&lt;li&gt;Mitigating risks such as infinite loops, unintended actions, or goal drift.&lt;/li&gt;
&lt;li&gt;Optimizing cost, latency, and efficient model usage.
Integrating agentic systems into business products and processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agentic Systems Architect
&lt;/h3&gt;

&lt;h4&gt;
  
  
  (Architect of Intelligent Agent-Based Systems)
&lt;/h4&gt;

&lt;p&gt;The Agentic Systems Architect is responsible for designing the architecture of systems powered by autonomous AI agents. This role defines how multiple agents perceive information, reason, make decisions, and execute actions in a coordinated way — ensuring scalability, security, and alignment with business objectives.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing scalable and resilient multi-agent architectures.&lt;/li&gt;
&lt;li&gt;Defining memory, planning, and decision-making structures.&lt;/li&gt;
&lt;li&gt;Designing coordination and communication mechanisms between agents.&lt;/li&gt;
&lt;li&gt;Integrating agents with APIs, databases, external tools, and enterprise systems.&lt;/li&gt;
&lt;li&gt;Establishing governance, control, and supervision rules for autonomous agents.&lt;/li&gt;
&lt;li&gt;Mitigating risks such as infinite loops, unintended actions, or strategic misalignment.&lt;/li&gt;
&lt;li&gt;Optimizing performance, latency, and model execution costs.&lt;/li&gt;
&lt;li&gt;Collaborating with product and business teams to translate strategic goals into functional autonomous systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI Product Manager
&lt;/h3&gt;

&lt;p&gt;The AI Product Manager defines, designs, and leads AI-powered products. This role connects AI technical capabilities with business and user needs, making strategic decisions about model usage, risk management, user experience, and technical feasibility to ensure AI delivers measurable value.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defining the vision and strategy for AI-based products.&lt;/li&gt;
&lt;li&gt;Identifying high-impact AI use cases.&lt;/li&gt;
&lt;li&gt;Prioritizing features considering impact, cost, and risk.
Collaborating with engineering and data teams on architecture and technical scope.&lt;/li&gt;
&lt;li&gt;Evaluating performance metrics (accuracy, latency, cost, adoption).&lt;/li&gt;
&lt;li&gt;Managing risks related to bias, privacy, and regulatory compliance.&lt;/li&gt;
&lt;li&gt;Designing user experiences that integrate AI clearly and responsibly.&lt;/li&gt;
&lt;li&gt;Continuously monitoring and optimizing product performance in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI Tech Lead
&lt;/h3&gt;

&lt;p&gt;The AI Tech Lead is the technical leader responsible for designing and overseeing the implementation of AI-based solutions within development teams. This role defines technical architecture, establishes best practices, and ensures AI systems are scalable, secure, and aligned with product and business goals.&lt;/p&gt;

&lt;p&gt;Acting as a bridge between strategy, product, and engineering, the AI Tech Lead ensures technical excellence across AI initiatives.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defining the technical architecture of AI-driven solutions.&lt;/li&gt;
&lt;li&gt;Leading the implementation of models, pipelines, and intelligent systems.&lt;/li&gt;
&lt;li&gt;Establishing quality, security, and governance standards in AI projects.&lt;/li&gt;
&lt;li&gt;Guiding teams on best practices for integrating LLMs, RAG systems, and agents.&lt;/li&gt;
&lt;li&gt;Reviewing code and validating AI-generated outputs.&lt;/li&gt;
&lt;li&gt;Making technical decisions regarding models, tools, and frameworks.&lt;/li&gt;
&lt;li&gt;Aligning technical decisions with product strategy and stakeholder objectives.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agentic AI Engineer
&lt;/h3&gt;

&lt;p&gt;The Agentic AI Engineer designs, develops, and implements autonomous AI agents. They build systems where agents can perceive, reason, plan, and act independently — integrating with tools, APIs, and real-world environments to automate complex processes.&lt;/p&gt;

&lt;p&gt;Their focus is turning AI models into operational agents that function reliably within production systems.&lt;/p&gt;

&lt;p&gt;Key activities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developing and implementing autonomous agents using LLMs and tools such as LangChain.&lt;/li&gt;
&lt;li&gt;Designing memory, planning, and decision-making mechanisms.&lt;/li&gt;
&lt;li&gt;Integrating agents with APIs, databases, and external tools.&lt;/li&gt;
&lt;li&gt;Building multi-agent architectures and coordination workflows.&lt;/li&gt;
&lt;li&gt;Implementing monitoring and behavior validation systems.&lt;/li&gt;
&lt;li&gt;Optimizing latency, cost, and execution efficiency.&lt;/li&gt;
&lt;li&gt;Testing, evaluating, and continuously improving agent performance.&lt;/li&gt;
&lt;li&gt;Here are a few examples of new roles created by the rapid adoption of AI in products and business processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know other roles created by this technological revolution, feel free to share them in the comments.&lt;/p&gt;

</description>
      <category>roles</category>
      <category>ai</category>
      <category>tech</category>
      <category>software</category>
    </item>
    <item>
      <title>How can a Junior Developer Defeat an AI?</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Sun, 22 Mar 2026 21:30:47 +0000</pubDate>
      <link>https://dev.to/mteheran/how-can-a-junior-developer-defeat-an-ai-34ha</link>
      <guid>https://dev.to/mteheran/how-can-a-junior-developer-defeat-an-ai-34ha</guid>
      <description>&lt;p&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%2Fyla4dwnlka1whghgyxk9.webp" 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%2Fyla4dwnlka1whghgyxk9.webp" alt="How can a Junior Developer Defeat an AI" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The massive use of artificial intelligence, along with the advent of new technologies and the release of hundreds of models and services based on this technology, represents a major shift in the paradigm of what it means to be a programmer and how we carry out our daily activities. Some time ago, I shared an article about what constitutes a new role for developers and programmers in the age of AI: taking on the responsibility of supervising what AI produces, in the article &lt;a href="https://dev.to/mteheran/from-programmer-to-ai-code-supervisor-18i6"&gt;From Programmer to Supervisor of AI-Generated Code&lt;/a&gt;. This role is becoming more common, but also more challenging for those who must assume it — especially junior developers or those just beginning a career in technology.&lt;/p&gt;

&lt;p&gt;The hiring dynamic has been transformed by artificial intelligence. However, we have not fully adopted the mindset of hiring junior developers who, together with AI, can generate projects and accelerate progress. On the contrary, many companies have chosen to reduce teams and rely on the best senior developers who, with their knowledge, expertise, and now AI skills, can maximize the value of these tools and focus on the most critical aspects of projects such as scalability, infrastructure, architecture, and product development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it more challenging for Junior developers to remain competitive in a world dominated by AI?
&lt;/h2&gt;

&lt;p&gt;Junior developers face many challenges entering the industry today, influenced by several additional factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;University students or those trained through online courses typically learn the fundamentals. However, in today’s work environment, many basic tasks are delegated to AI. This can limit opportunities for juniors to practice, make mistakes, and strengthen their technical judgment through direct experience.&lt;/li&gt;
&lt;li&gt;There is also an expansion in the range of technologies and phases of the software development process that must be mastered. With AI, we now need to understand more stages of software development — from testing and automation with DevOps tools to the generation of Proofs of Concept (PoC). Since AI reduces the time required for technical tasks, creativity and broader system understanding are increasingly valued.&lt;/li&gt;
&lt;li&gt;There has also been a paradigm shift in what is expected from a junior developer. We have moved from workshops and training programs to a reality with stricter requirements, where complex concepts, certifications, and experience with AI are demanded from the start.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recommendations for Junior developers in the AI era
&lt;/h2&gt;

&lt;p&gt;Although the landscape may seem challenging, we can highlight some actions to become more competitive and build the profile the market truly needs in this pivotal moment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is important to learn AI, not just use the tools. This includes understanding how LLMs are improved, prompt engineering techniques, agentic architectures, and the creation of intelligent agents. The deeper we go into these concepts and the more importance we give them, the better we will understand what AI does and how to use it effectively.&lt;/li&gt;
&lt;li&gt;Use AI to understand and deepen knowledge across all phases of development. Unit and integration testing were often neglected or undervalued due to the time required for implementation. Now, any developer who understands testing concepts and knows the libraries used to build them can quickly generate all the tests a project requires.&lt;/li&gt;
&lt;li&gt;Strengthen the foundations and core concepts of programming and AI. Now more than ever, understanding what a design pattern is, what an architecture like Clean Code represents, and knowing best practices is essential to critically evaluate what AI produces and what the product or client truly requires.&lt;/li&gt;
&lt;li&gt;Value physical and mental health, continuous learning, and soft skills. Products are still designed for humans and for humanity, and creativity is becoming one of the most valuable differentiators in what we build. To enhance creativity, it is necessary to care for physical and mental health, maintain spaces for reflection, and cultivate a mindset of continuous learning.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: The End of the Developer Who Only Types
&lt;/h2&gt;

&lt;p&gt;We are witnessing the end of a stage in the profession: the developer whose main value was manually writing code for hours. AI can now generate functions, classes, complete APIs, and even functional prototypes in minutes. The purely mechanical task of typing code is losing relevance. But this does not mean the death of the developer. It means evolution.&lt;/p&gt;

&lt;p&gt;In the new AI era, value no longer lies in the speed of our fingers, but in the depth of our minds. The professional who reflects, analyzes, questions, designs, and creates will be more necessary than ever. AI amplifies execution, but judgment remains human.&lt;/p&gt;

&lt;p&gt;The competitive advantage will no longer be “who programs more,” but “who understands the problem better,” “who asks better questions,” and “who designs solutions with strategic vision.”&lt;/p&gt;

&lt;p&gt;In this new stage, programming is more about finding solutions than just typing code; it reflects the core essence of engineering.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developer</category>
      <category>programming</category>
      <category>devlife</category>
    </item>
    <item>
      <title>The Essential Skills of an AI Code Supervisor</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Thu, 04 Dec 2025 05:20:49 +0000</pubDate>
      <link>https://dev.to/mteheran/the-essential-skills-of-an-ai-code-supervisor-3h6k</link>
      <guid>https://dev.to/mteheran/the-essential-skills-of-an-ai-code-supervisor-3h6k</guid>
      <description>

&lt;p&gt;The software industry is undergoing a historic shift. In just a few years, we've moved from prohibiting the use of generative AI tools to making them an indispensable requirement for productivity. A few weeks ago, I published an article introducing for the first time the concept of an AI-Generated Code Supervisor (From Programmer to AI-Generated Code Supervisor). Continuing with this concept, this article delves deeper into the essential skills for this emerging role, which is rapidly becoming an industry trend.&lt;br&gt;
This new, specialized role of AI Code Supervisor is a hybrid figure that combines critical thinking, deep technical knowledge, and professional judgment capable of detecting errors, inconsistencies, and incorrect decisions that AI cannot yet comprehend.&lt;br&gt;
This role does not replace the traditional programmer but redefines their responsibilities and the way they apply their knowledge to complete daily tasks. Let's analyze the most important skills for this role.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Analytical Ability: The Fundamental Skill
&lt;/h2&gt;

&lt;p&gt;The supervisor must assume that code generated by AI is not trustworthy by default - even if it compiles and looks correct.&lt;br&gt;
AI can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Misinterpret business rules.&lt;/li&gt;
&lt;li&gt;Invent non-existent behaviors.&lt;/li&gt;
&lt;li&gt;Overlook edge cases.&lt;/li&gt;
&lt;li&gt;Produce code that appears correct but fails under real loads.&lt;/li&gt;
&lt;li&gt;Regenerate files or portions of code while omitting crucial steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, analytical ability becomes the first and most critical skill. It involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deeply understanding the problem before validating the solution.&lt;/li&gt;
&lt;li&gt;Verifying assumptions.&lt;/li&gt;
&lt;li&gt;Contrasting the code against requirements and architecture.&lt;/li&gt;
&lt;li&gt;Detecting logical or flow inconsistencies.&lt;/li&gt;
&lt;li&gt;Thoroughly testing functionality and potential scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI generates code, but the users will be human.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Solid Knowledge of Best Practices and Clean Code
&lt;/h2&gt;

&lt;p&gt;A common flaw in AI-generated code is the lack of consistency or failure to apply organizational standards for best practices and quality. AI often generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excessively long methods.&lt;/li&gt;
&lt;li&gt;Unnecessarily complex structures.&lt;/li&gt;
&lt;li&gt;Ambiguous names.&lt;/li&gt;
&lt;li&gt;Duplication.&lt;/li&gt;
&lt;li&gt;Poorly organized dependencies.&lt;/li&gt;
&lt;li&gt;Code structured without design patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A code supervisor must apply principles such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean Code.&lt;/li&gt;
&lt;li&gt;SOLID.&lt;/li&gt;
&lt;li&gt;KISS.&lt;/li&gt;
&lt;li&gt;YAGNI.&lt;/li&gt;
&lt;li&gt;Design patterns and anti-patterns.&lt;/li&gt;
&lt;li&gt;Style standards.&lt;/li&gt;
&lt;li&gt;Modern techniques like Hexagonal Architecture or DDD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this conceptual framework, it is impossible to evaluate whether the AI produced something correct or merely something that "works."&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Software Architecture Knowledge
&lt;/h2&gt;

&lt;p&gt;AI can generate code, but it doesn't design complete systems. It often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lacks understanding of context boundaries.&lt;/li&gt;
&lt;li&gt;Introduces unnecessary coupling.&lt;/li&gt;
&lt;li&gt;Creates structures that don't scale.&lt;/li&gt;
&lt;li&gt;Mixes responsibilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The supervisor must possess architectural judgment to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correct course when the AI makes poor decisions.&lt;/li&gt;
&lt;li&gt;Split components appropriately.&lt;/li&gt;
&lt;li&gt;Ensure modules adhere to the defined architecture.&lt;/li&gt;
&lt;li&gt;Maintain the overall system view.&lt;/li&gt;
&lt;li&gt;Consider future functionalities or changes in the architectural design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture remains human territory, and the AI is merely an assistant within it.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Attention to Detail: The Soft Skill That Saves Projects
&lt;/h2&gt;

&lt;p&gt;While AI automates complex tasks, small errors can still have enormous consequences. A mispassed parameter, an inverted conditional, or an unhandled null value can cause failures the AI doesn't detect.&lt;br&gt;
Attention to detail enables the supervisor to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review code line-by-line when necessary.&lt;/li&gt;
&lt;li&gt;Identify inconsistencies between documentation and code.&lt;/li&gt;
&lt;li&gt;Verify input and output data.&lt;/li&gt;
&lt;li&gt;Validate names, structures, and contracts.&lt;/li&gt;
&lt;li&gt;Perform more robust testing after implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this skill, the supervisor becomes just another automatic approver - precisely what we must avoid.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Clear Communication and Mastery of Prompt Engineering
&lt;/h2&gt;

&lt;p&gt;The AI code supervisor doesn't just write code: they write instructions. A significant part of the role involves dialoguing with the AI - providing context, correcting its course, and iteratively refining requests. Modern AI tools offer powerful functionalities like execution plans and rules to better guide and set parameters for the desired output.&lt;br&gt;
This demands the ability to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express requirements with precision.&lt;/li&gt;
&lt;li&gt;Eliminate ambiguity.&lt;/li&gt;
&lt;li&gt;Understand how to structure effective prompts.&lt;/li&gt;
&lt;li&gt;Request comparisons, alternatives, or in-depth analyses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mastering prompts is mastering the true power of AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  General Recommendations for AI-Generated Code Supervisors
&lt;/h2&gt;

&lt;p&gt;If you are working on a project where code is predominantly AI-generated - using tools like GitHub Copilot, Cursor, or Amazon Q - with rapid delivery cycles, and where AI has become a standard, freely used or even mandatory tool, then your role is already evolving into that of an AI-Generated Code Supervisor.&lt;br&gt;
In these scenarios, certain critical points require your focused attention as a supervisor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrutinize every detail of the generated code. Rewrite prompts as many times as necessary until the output is correct. The prompt is your primary control mechanism.&lt;/li&gt;
&lt;li&gt;Test exhaustively and think beyond the "happy path." After implementation, run the code repeatedly. Assume complex, edge-case, and failure scenarios. Do not settle for superficial functionality.&lt;/li&gt;
&lt;li&gt;Implement a robust testing strategy. With AI, there is no excuse to skip tests. Implement unit tests, integration tests, and automated testing suites. Let the AI help you generate them, but you must define the scope and validate the results.&lt;/li&gt;
&lt;li&gt;Enforce code quality and cleanliness. Eliminate warnings, use static code analysis tools (linters), and maintain clean, well-documented code. The speed of AI generation makes this discipline more crucial, not less.&lt;/li&gt;
&lt;li&gt;Invest the time saved by AI into elevating project standards. Use the gained efficiency to keep projects meticulously updated, documented, and maintained with high testing standards. Moving from writing code to curating and guaranteeing a quality codebase.&lt;/li&gt;
&lt;li&gt;Leverage all available tools to improve AI context. Create examples, define custom rules and instructions, and build a library of effective, reusable prompts. Treat your interaction with the AI as a high-leverage engineering task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI does not eliminate the developer; it elevates them to a more strategic level and transforms how they execute their tasks. However, this new paradigm demands that we strengthen our analytical skills and critical judgment more than ever.&lt;br&gt;
The professionals who cultivate these supervisory skills will become the most valuable assets in the new era of AI-powered software development.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>management</category>
    </item>
    <item>
      <title>Automating Code Reviews with Junie by JetBrains</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Tue, 21 Oct 2025 02:22:45 +0000</pubDate>
      <link>https://dev.to/mteheran/automating-code-reviews-with-junie-by-jetbrains-jh2</link>
      <guid>https://dev.to/mteheran/automating-code-reviews-with-junie-by-jetbrains-jh2</guid>
      <description>&lt;p&gt;Junie is a new power and advanced artificial intelligence (AI) that helps the developers to create, review and analyze code to improve the quality and avoid common issues that sometimes we cannot see during the development process.&lt;/p&gt;

&lt;p&gt;Junie is integrated in all the IDEs offered by JetBrains for this demo. We will use Rider and also a C# code related to a simple api that uses the minimal api template provided by dotnet. &lt;/p&gt;

&lt;p&gt;I created a new branch and I commited some changes that include bad practices and issues. Here is the list of issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hardcode id used for testing proposal
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id = 1; //testing with item 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;bad formatted code (this code looks like Python)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (region is null)
{
     return

       Results.NotFound();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Some unuseful or innecesary conditions:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!isValidSort)
{
   if (region is not null)
   {
       if (db is not null)
       {
         return Results.BadRequest(RequestMessages.BadRequest);
       }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A hardcoded value is embedded within a query. Sometimes this is valid but not for this case because it refers to the Id.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var region = await db.Regions.Include(p =&amp;gt; p.Departments)
                    .SingleOrDefaultAsync(p =&amp;gt; p.Id == 0);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After addressing these issues, we can use Junie to review our code and identify any problems before creating a pull request and moving forward with the changes. This is how Junie looks in Rider when you have a project open:&lt;/p&gt;

&lt;p&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%2Fucmncmnp00vfco62t2hz.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%2Fucmncmnp00vfco62t2hz.png" alt=" " width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the chat we need to write the prompt depending on what we want to do with the code. To perform a codereview of the git changes in the branch this is a possible prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Execute an in-depth code review of the current branch, analyzing all committed changes. Generate a document summarizing your findings and ensure to incorporate every recommendation into the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Junie will perform some commands in order to complete the instructions requested in the promtp. &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%2Fg11q1piwr524g20xg1j4.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%2Fg11q1piwr524g20xg1j4.png" alt=" " width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing all the steps planned by Junie we have now the changes applied in the code and we can see how effective the code review&lt;/p&gt;

&lt;p&gt;The hardcoded ID and improperly formatted code have been identified:&lt;/p&gt;

&lt;p&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%2F4ozof0trd9pdea00xy3p.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%2F4ozof0trd9pdea00xy3p.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Junie identified unnecessary conditions, a hardcoded ID in the query, typos in the department variable, and an issue in the produces function where it's returning department instead of regions.&lt;/p&gt;

&lt;p&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%2F9xn382frhubt1929kmhq.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%2F9xn382frhubt1929kmhq.png" alt=" " width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, Junie proves to be an exceptional tool for conducting code reviews. I am truly impressed by its ability to not only identify newly introduced issues but also to catch additional changes made in previous commits around the same code. &lt;/p&gt;

&lt;p&gt;We can highlight some advantages of using Junie in our local environment to perform the code review:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We can detect additional changes or issues code analyzing our changes but also all the code around&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can save time and resources by opting to perform the whole code review in the pull request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can generate additional code like documentation and relese notes, creating a prompt with more details and steps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I suggest taking time and working with this AI for some weeks so you can see the potential of this tool. &lt;/p&gt;

</description>
      <category>junie</category>
      <category>ai</category>
      <category>codereview</category>
      <category>tool</category>
    </item>
    <item>
      <title>From Programmer to AI Code Supervisor</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Fri, 10 Oct 2025 20:24:38 +0000</pubDate>
      <link>https://dev.to/mteheran/from-programmer-to-ai-code-supervisor-18i6</link>
      <guid>https://dev.to/mteheran/from-programmer-to-ai-code-supervisor-18i6</guid>
      <description>&lt;p&gt;A couple of years ago, mentioning Generative AI in software companies led to skepticism and strict security measures. IT departments viewed tools like ChatGPT and GitHub Copilot as potential sources of intellectual property leaks and significant risks. Corporate policies were explicit: “prohibited or strictly regulated usage.” The vast majority of programmers used artificial intelligence (AI) at their own risk and without official permission.&lt;/p&gt;

&lt;p&gt;But industry standards changed in the blink of an eye. What was once a threat has now become the standard. The question is no longer “Should we use AI?” but “How can we integrate it more efficiently?” Some companies are now measuring developer productivity based on their adoption and effective use of tools. We have moved from prohibition to a tacit obligation.&lt;/p&gt;

&lt;p&gt;The evidence of this change is everywhere, and we developers have witnessed it. Recent studies and surveys paint a clear picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.blog/wp-content/uploads/2024/08/2024-Developer-Survey-United-States.pdf" rel="noopener noreferrer"&gt;GitHub Survey (October 2024)&lt;/a&gt;: Revealed that 99% of developers in the United States already use AI tools in their workflows. GitHub Copilot, its flagship tool, claims to be responsible for generating up to 40% of the code in supported languages.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://survey.stackoverflow.co/2024/ai#sentiment-and-usage-ai-select" rel="noopener noreferrer"&gt;JetBrains Survey (Developer Survey 2024)&lt;/a&gt;: Corroborates this trend, indicating that over 70% of developers have incorporated AI into their processes, primarily for autocompletion, code generation, and error detection.
This has given rise to a flourishing ecosystem of tools. From Copilot and Amazon CodeWhisperer to specialized courses teaching “Prompt Engineering for Developers” and mandatory ongoing training within companies. The critical skill is no longer just knowing how to program, but knowing how to orchestrate AI to program for you or alongside you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Experience: The Project Where AI Writes the Code (And Everything Else)
&lt;/h3&gt;

&lt;p&gt;My current project has demonstrated the shift in software roles during a legacy migration from Java to C#. This is not a traditional migration project; it is a laboratory of extreme automation based on artificial intelligence where our role as programmers has been radically redefined.&lt;/p&gt;

&lt;p&gt;These are the steps we have followed, working hand-in-hand with AI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ticket and Documentation Generation: User stories are no longer written manually. An AI prompt analyzes the legacy Java code and automatically generates the ticket description, acceptance criteria, and necessary technical documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;C# Code Generation: The core of the process. We use advanced prompts and AI tools to automatically translate Java functions and classes into C#. Our task is not to write code from scratch, but to provide the precise context.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit Test Creation: After coding and verifying its functionality, you can easily create unit tests with a simple prompt in Copilot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated Code Review: The code review process is also AI-assisted. A tool handles static analysis, checks patterns, suggests improvements, and detects obvious inconsistencies before a human peer reviews it. All of this happens in the pull request, where feedback is provided through comments on the code lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validation via Automated Testing: The method for testing the fidelity of the migration is very simple. Automated tests are run, feeding the same data into both systems (the legacy Java and the new C#), and the results are compared. If they match, the migrated code is correct.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this ecosystem, my primary function has ceased to be “programming.” I have become a supervisor of AI-generated code. My value lies in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing the right prompts to get the desired output.&lt;/li&gt;
&lt;li&gt;Understanding the business context to validate that the AI has not made a conceptual error.&lt;/li&gt;
&lt;li&gt;Making high-level architectural decisions that the AI is not yet capable of assuming.&lt;/li&gt;
&lt;li&gt;Keeping constant communication with the client to avoid migrating outdated components and to enhance the code during the migration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion and Reflection:
&lt;/h3&gt;

&lt;p&gt;This new role of “supervisor” is incredibly efficient and undoubtedly marks the future of our craft. However, an uncomfortable and inevitable question arises: Along the way, are we beginning to lose the analytical capacity and programming logic that has always characterized us?&lt;/p&gt;

&lt;p&gt;The dependence on AI for routine tasks frees us to think about more complex problems. But what about the junior developer who no longer needs to struggle for hours with a loop or a data structure because the AI provides it instantly? Are they missing the opportunity to forge their intuition and mental ability for problem-solving?&lt;/p&gt;

&lt;p&gt;Programming was never just about the final code; it was about the thought process, the methodical decomposition of a problem, the teamwork to build code from ideas, and the creative search for a solution. If we outsource that thought process to an AI, we risk becoming technicians who only know how to push the right button, without truly understanding the machinery underneath.&lt;/p&gt;

&lt;p&gt;The challenge for the new generation of developers (and for those of us in this transition) will be to find the balance. We must embrace the power of AI without failing to actively cultivate our skills in logical thinking, deep analysis, and creative problem-solving. There is no near-future scenario where AI has total control over a project and human intervention becomes unnecessary. We build software with AI for use by human beings, and as long as this continues, our role as programmers will remain relevant. Maintaining analysis skills and logic is not optional; detecting AI errors as code supervisors will be a necessary skill for competitiveness in the technology fields in the near future.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Full-Stack Developer, myth or reality?</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Thu, 03 Oct 2024 13:51:51 +0000</pubDate>
      <link>https://dev.to/mteheran/full-stack-developer-myth-or-reality-3e9m</link>
      <guid>https://dev.to/mteheran/full-stack-developer-myth-or-reality-3e9m</guid>
      <description>&lt;p&gt;In the past decade, the term "Full-Stack developer" has become popular, referring to a programmer skilled in handling all aspects of modern web projects. Full-Stack developers are experts in front-end and back-end development, covering both the user interface and the server side. Their ability to work in both areas gives them a complete view of projects and improves communication between teams. A major challenge they face is the rapid evolution of technology, which demands ongoing learning to stay updated with the latest tools and frameworks. The requirement to master various technologies, patterns, architectures and trends raises questions about the feasibility of having professionals who meet all these characteristics. It is important to note that a more comprehensive approach is now being considered when defining Full-Stack profiles, incorporating skills such as cloud service management, the use of DevOps tools and the integration of artificial intelligence services.&lt;/p&gt;

&lt;h3&gt;
  
  
  History
&lt;/h3&gt;

&lt;p&gt;Developers have always had to adapt to new technologies and learn different tools to create robust applications. User interface design used to be mainly performed in IDEs like Visual Studio, Dreamweaver, and NetBeans. These interfaces were much simpler and outdated, while developers focused their attention on optimizing workflows and business logic. The evolution of Web 2.0, coupled with the introduction of HTML5 and innovative JavaScript libraries like Ember.js, Angular.js, and Backbone.js, has greatly expanded the possibilities for front-end development. As a result, the demand for programmers skilled in these technologies has surged, becoming a prominent trend in the industry. By that time, a large number of startups were started (Airbnb, Uber, Spotify) that with their success demonstrated the importance of improving the experience for users and creating technology-based businesses. &lt;br&gt;
Those changes in the industry have led to a requirement for more comprehensive profiles due to project dynamics and budget considerations. A more versatile developer can potentially lower costs associated with hiring multiple programmers and can facilitate the quicker implementation of new features, highlighting the significance of the Full-Stack profile. Something to highlight is that the release of Node.js significantly increased the search for this profile, since using the same programming language (JavaScript) on the front-end and back-end side would theoretically facilitate acquiring the necessary skills to work on both sides of the architecture of an application.&lt;/p&gt;

&lt;h3&gt;
  
  
  A great back-end is a bad front-end or vice-versa
&lt;/h3&gt;

&lt;p&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%2Fzsg0erwcearae16p4b39.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%2Fzsg0erwcearae16p4b39.png" alt="Full-stack developer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many believe that Full-Stack developers excel in one area of development but struggle in another. This isn't due to a rule but rather the difficulty of mastering all the necessary technical skills. For example, a very strong developer on the front-end side with knowledge of architecture and user experience can hardly be an expert in cloud-focused microservices architecture patterns. This is not an impossibility, but considering the advanced technical knowledge needed it is very difficult to achieve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal conclusion based on my professional career
&lt;/h3&gt;

&lt;p&gt;I've worked with many skilled professionals and developers, but I've never seen anyone excel equally at both front-end and back-end development. Typically, their expertise in development or specific technologies is shaped by the challenges they've faced in projects and their personal interests. I believe that the Full-Stack profile can be effective in certain situations, even if it's a controversial opinion.&lt;/p&gt;

&lt;p&gt;Some companies implement a design system to build their interfaces based on an architecture with reusable controls and components that facilitate front-end development. They also build all the business logic in the back-end and use ORMs (Object-relational mapping) to control changes and connection to the database. This creates a convenient scenario for a Full-Stack profile where you can make back-end and front-end changes in the same user story (branch, pull request, etc...) and finish developments faster. This is a risk that can affect the quality of development, especially on the front-end side, but it is surely a risk that many companies are willing to take for the benefits it brings.&lt;/p&gt;

&lt;p&gt;Another very common scenario in recent years are applications focused on cloud services or based on artificial intelligence services, which means that the complexity of the back-end is reduced and development is focused on the user experience and adaptability of the apps.&lt;/p&gt;

&lt;p&gt;The concept of Full-stack development remains debated within the developer community, but it is a highly sought-after skill in the industry. Having expertise in both web and backend development provides a better understanding of software projects and opens up more job opportunities. Everything indicates that we will always be stronger on one of the sides of software development or in some technology, but today having artificial intelligence tools and solid programming bases as a help we can solve complex challenges in every aspect and phase of the development of an application.&lt;/p&gt;

</description>
      <category>reflection</category>
    </item>
    <item>
      <title>dotnet LATAM Day 2024</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Tue, 10 Sep 2024 22:09:17 +0000</pubDate>
      <link>https://dev.to/mteheran/dotnet-latam-day-2024-52od</link>
      <guid>https://dev.to/mteheran/dotnet-latam-day-2024-52od</guid>
      <description>&lt;p&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%2F3riamsqadio945gvpl8s.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%2F3riamsqadio945gvpl8s.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Estás invitad@ al Dotnet LATAM Day!&lt;/p&gt;

&lt;p&gt;Únete a nosotros en un evento imperdible donde exploraremos lo mejor de las tecnologías Microsoft. Descubre librerías, productos y servicios innovadores creados con Blazor, .NET, ASP.NET, Azure y otras tecnologías Microsoft. Este es el lugar perfecto para adquirir conocimientos, encontrar inspiración y conectarte con otros apasionados del desarrollo en un evento online completamente gratuito.&lt;/p&gt;

&lt;p&gt;¿Cuándo? 24 de octubre 2024 – 2PM GTM-5, bogotá, quito,&lt;/p&gt;

&lt;p&gt;¿Dónde? Será transmitido por los canales de Youtube de mteheran.dev y elcamino.dev: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@Mteherandev" rel="noopener noreferrer"&gt;Mteheran.dev – Youtube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@ElCaminoDev" rel="noopener noreferrer"&gt;El Camino Dev – YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Call for Speakers abierto hasta el 4 de octubre:&lt;br&gt;
&lt;a href="https://sessionize.com/dotnet-latam-day-2024/" rel="noopener noreferrer"&gt;Call for speakers (hasta el 4 de octubre): Envía tu charla&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prepárate para un día lleno de charlas, talleres y oportunidades de networking. ¡No te lo pierdas!&lt;/p&gt;

&lt;p&gt;Suscribete a nuestros canales de Youtube y asegura tu lugar en el Dotnet LATAM Day.&lt;/p&gt;

&lt;p&gt;¡Te esperamos!&lt;/p&gt;

</description>
      <category>event</category>
      <category>conference</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Free Books for Flutter Developers</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Tue, 13 Feb 2024 16:45:34 +0000</pubDate>
      <link>https://dev.to/mteheran/free-books-for-flutter-developers-1h9l</link>
      <guid>https://dev.to/mteheran/free-books-for-flutter-developers-1h9l</guid>
      <description>&lt;p&gt;This is a list of books to learn flutter for free: &lt;/p&gt;

&lt;h3&gt;
  
  
  Flutter Succinctly
&lt;/h3&gt;

&lt;p&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%2F3j93dkhj7h9rj8ti64nn.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%2F3j93dkhj7h9rj8ti64nn.png" alt="Flutter Succinctly" width="250" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flutter is an open-source mobile application development SDK developed by Google with support for both Android and iOS using the same codebase. Written in C, C++, and Dart, and using the Skia Graphics Engine, Flutter also offers a rich set of fully customizable widgets for building native interfaces, including the Material Design library and Cupertino (iOS-flavored) widgets, rich motion APIs, and hot reload. In Flutter Succinctly, Ed Freitas will take you through creating a fully functional app to help you assess whether Flutter is the right choice for your mobile development needs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/succinctly-free-ebooks/flutter-succinctly" rel="noopener noreferrer"&gt;https://www.syncfusion.com/succinctly-free-ebooks/flutter-succinctly&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Flutter UI Succinctly
&lt;/h3&gt;

&lt;p&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%2Fxgszl6w248iovr2ulh4y.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%2Fxgszl6w248iovr2ulh4y.png" alt="Flutter UI Succinctly" width="250" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flutter made quite the impact when it landed in the cross-platform mobile framework landscape. Developed by Google, open source, targeting iOS and Android, smooth animations and motion, platform awareness, hot reload—the list of highlights goes on and on, demonstrating why Flutter is a worth any mobile developer’s attention. In Flutter UI Succinctly, Ed Freitas explores the essentials of constructing user interfaces with Flutter, showing off how a handful of Flutter’s built-in widgets and tools can serve as a springboard to creating apps with impressive interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.syncfusion.com/succinctly-free-ebooks/flutter-ui-succinctly" rel="noopener noreferrer"&gt;https://www.syncfusion.com/succinctly-free-ebooks/flutter-ui-succinctly&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Flutter Tutorials
&lt;/h3&gt;

&lt;p&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%2F572rytqu935y2yv5cy98.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%2F572rytqu935y2yv5cy98.png" alt="Flutter Tutorials" width="259" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tutorial walks through the basics of Flutter framework, installation of Flutter SDK, &lt;br&gt;
setting up Android Studio to develop Flutter based application, architecture of Flutter&lt;br&gt;
framework and developing all type of mobile applications using Flutter framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tutorialspoint.com/flutter/flutter_tutorial.pdf" rel="noopener noreferrer"&gt;https://www.tutorialspoint.com/flutter/flutter_tutorial.pdf&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Flutter Libraries We Love
&lt;/h3&gt;

&lt;p&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%2F8k9pvvlrfluqw3nhgmn6.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%2F8k9pvvlrfluqw3nhgmn6.png" alt="Flutter Libraries We Love" width="192" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We focused on 11 different Flutter library categories. After selecting the categories, &lt;br&gt;
we made a list of libraries under each category and chose the libraries we wanted to &lt;br&gt;
highlight the most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.codemagic.io/flutter-libraries-ebook-by-codemagic/ebook-flutter-libraries-we-love-by-codemagic.pdf" rel="noopener noreferrer"&gt;https://blog.codemagic.io/flutter-libraries-ebook-by-codemagic/ebook-flutter-libraries-we-love-by-codemagic.pdf&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>book</category>
      <category>free</category>
    </item>
    <item>
      <title>How to read zip files with SharpZip library in C#</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Fri, 09 Feb 2024 17:52:41 +0000</pubDate>
      <link>https://dev.to/mteheran/how-to-read-zip-files-with-sharpzip-library-in-c-49ib</link>
      <guid>https://dev.to/mteheran/how-to-read-zip-files-with-sharpzip-library-in-c-49ib</guid>
      <description>&lt;p&gt;SharpZip library is a great library to work with compressed files like .zip. This library supports Zip, GZip, BZip2, and Tar.&lt;/p&gt;

&lt;p&gt;To use this library, add it to your project using the package manager in Visual Studio or with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package SharpZipLib &lt;span class="nt"&gt;--version&lt;/span&gt; 1.4.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we need to add the following namespace to the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ICSharpCode.SharpZipLib.Zip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then to read the file, we need to define the path; it could be a relative or absolute route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myZipPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test.zip"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this simple code snippet, we can loop through all the files in the zip and read their content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipFile&lt;/span&gt; &lt;span class="n"&gt;zipFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ZipFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myZipPath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipEntry&lt;/span&gt; &lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;zipFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zipFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInputStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Content: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadToEnd&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&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;p&gt;You can also check if the ZipEntry value is a folder or a file to avoid issues reading the information. We have a simple condition. We can validate it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipFile&lt;/span&gt; &lt;span class="n"&gt;zipFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ZipFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myZipPath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipEntry&lt;/span&gt; &lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;zipFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsDirectory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zipFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInputStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Content: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadToEnd&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&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;



</description>
      <category>sharpzip</category>
      <category>csharp</category>
      <category>zip</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Comparison of Automation Frameworks: Selenium, Playwright and Cypress</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Thu, 01 Feb 2024 20:10:21 +0000</pubDate>
      <link>https://dev.to/mteheran/comparison-of-automation-frameworks-selenium-playwright-and-cypress-3h8i</link>
      <guid>https://dev.to/mteheran/comparison-of-automation-frameworks-selenium-playwright-and-cypress-3h8i</guid>
      <description>&lt;p&gt;In modern software development, test automation has become an indispensable element, enabling QA teams and developers to efficiently and effectively verify the quality of their applications. Several tools have emerged to facilitate this process, such as Playwright, Selenium, and Cypress being some prominent options. This comparison will analyze and contrast the three leading tools in test automation, showcasing their strengths, weaknesses, and distinctive features.&lt;/p&gt;

&lt;p&gt;Selenium: Widely used, it supports multiple languages and browsers, ideal for end-to-end testing.&lt;/p&gt;

&lt;p&gt;Cypress: Modern approach, designed for in-browser testing, stands out for its simplicity, speed and efficiency in integration and unit testing.&lt;/p&gt;

&lt;p&gt;Playwright: It is versatile, allowing the automation of advanced tasks, such as emulation of mobile devices. It stands out for its ability to work in multiple browsers and run test in parallel.&lt;/p&gt;

&lt;h2&gt;
  
  
  General information
&lt;/h2&gt;

&lt;p&gt;In the following table you will learn the general information for each framework:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Selenium&lt;/th&gt;
&lt;th&gt;Playwright&lt;/th&gt;
&lt;th&gt;Cypress&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Release year&lt;/td&gt;
&lt;td&gt;2004&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer&lt;/td&gt;
&lt;td&gt;Jason Huggins -Community&lt;/td&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;Cypress - Community&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;OpenSource&lt;/td&gt;
&lt;td&gt;OpenSource&lt;/td&gt;
&lt;td&gt;OpenSource-Cloud license&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Written in&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Selenium is the oldest and still widely used framework/library for Automation. Playwright, on the other hand, is the newest framework, but their popularity is increasing quickly in the community. Microsoft created Playwright to address common challenges in Selenium, as well as improve integration with DevOps tools and cloud services.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Selenium&lt;/th&gt;
&lt;th&gt;Playwright&lt;/th&gt;
&lt;th&gt;Cypress&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Languages&lt;/td&gt;
&lt;td&gt;JavaScript, Java, Ruby, others&lt;/td&gt;
&lt;td&gt;JavaScript, Java, C#, Python&lt;/td&gt;
&lt;td&gt;JavaScript only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser supported&lt;/td&gt;
&lt;td&gt;Almost all of them&lt;/td&gt;
&lt;td&gt;Chromium, Firefox, Webkit&lt;/td&gt;
&lt;td&gt;Chromium, Firefox, Webkit, Electron&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;Library&lt;/td&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution time&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Very Fast&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI extension&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The main feature in Playwright is the performance and support for modern programming languages and frameworks. Selenium has the best support for old browsers and programming languages. Cypress has only support for the JavaScript ecosystem.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Popularity
&lt;/h2&gt;

&lt;p&gt;Let's review the popularity and numbers of downloads in npm. Check the following picture:&lt;/p&gt;

&lt;p&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%2Fdndz8fihy034jg5r50pn.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%2Fdndz8fihy034jg5r50pn.png" alt="Popularity comparisson Playwright, Selenium, Cypress" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the last months, Playwright has overcome selenium in the number of downloads, stars and contributors on GitHub. This means a great appreciation by the community to this framework.&lt;/p&gt;

&lt;p&gt;Selenium is widely regarded as the top choice for Java and Python due to its extensive implementation in major projects over many years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demos
&lt;/h2&gt;

&lt;p&gt;In the following sections, we will reproduce the first steps to create our first automation test for these 3 technologies.&lt;/p&gt;

&lt;p&gt;For these demos we will use the following web page: &lt;a href="https://www.saucedemo.com/" rel="noopener noreferrer"&gt;https://www.saucedemo.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is to perform the login and validate that it was successful on the following screen: &lt;/p&gt;

&lt;p&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%2Fsqeljkl6jo5v6vg1nrc0.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%2Fsqeljkl6jo5v6vg1nrc0.png" alt="Login page saucedemo" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cypress
&lt;/h3&gt;

&lt;p&gt;Let's review the prerequisites and commands to create our first test in Cypress.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequirements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18 or 20&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to an empty folder where you want to create the project&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;npm install cypress --save-dev&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then use this command to execute the project: &lt;code&gt;npx cypress open&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now in the folder &lt;strong&gt;cypress/e2e&lt;/strong&gt; create a new test with the name &lt;code&gt;spec.cy.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add the following code to create a new test for the login.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sauce demo&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;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login pass&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;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.saucedemo.com/#/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#user-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standard_user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret_sauce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#login-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.app_logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;have.text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Swag Labs&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;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In cypress, we type &lt;strong&gt;cy&lt;/strong&gt; to use the API and call the functions to detect elements, set values and navigate in the page. The code is petty simple and easy to understand. We use &lt;strong&gt;#element-id&lt;/strong&gt; cal get elements by Id and &lt;strong&gt;.class&lt;/strong&gt; to get the element by CSS class. We don't need to install extra libraries or components to create our first tests. &lt;/p&gt;

&lt;h3&gt;
  
  
  Selenium
&lt;/h3&gt;

&lt;p&gt;Let's review the prerequisites and commands to create our first test in Selenium with JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequirements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18 or 20&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to an empty folder where you want to create the project&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute the following commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install selenium-webdriver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install chromedriver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install mocha&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: selenium-webdriver is used to interact with the browser, chromedriver is used to execute the test in chrome so Selenium can control it and mocha help us to create the test like a simple unit test and capture the result.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a file &lt;code&gt;test.js&lt;/code&gt; where the test will be located&lt;/li&gt;
&lt;li&gt;Add the following code to perform the test on the login page with Selenium:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Chrome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selenium-webdriver/chrome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selenium-webdriver&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selenium-webdriver/testing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nf"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Should be able to Test Command line arguments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;headless&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setChromeOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forBrowser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chrome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.saucedemo.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;setTimeouts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;implicit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;sendKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standard_user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;sendKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret_sauce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;textLogo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;className&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app_logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Swag Labs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textLogo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&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;p&gt;Selenium has a better experience in other programming languages, like Java, Python and C#. Since Selenium is a library, we need to install other libraries to complement it. And install the drivers to connect with the browser where we want to run the test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Playwright
&lt;/h3&gt;

&lt;p&gt;Let's review the prerequisites and commands needed to create our first test in Playwright with JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequirements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18 or 20&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to an empty folder where you want to create the project&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm init playwright@latest&lt;/code&gt; to create the base project&lt;/li&gt;
&lt;li&gt;Then use this command to execute the tests: &lt;code&gt;npx playwright test&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a new file &lt;code&gt;mytest.spec.js&lt;/code&gt; in the folder &lt;strong&gt;tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add the following code to test the login page using Playwright:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login pass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&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;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.saucedemo.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&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;locator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#user-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;standard_user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&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;locator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secret_sauce&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&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;locator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#login-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Expect a title "to contain" a substring.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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;locator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.app_logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toHaveText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Swag Labs&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;p&gt;In playwright, we use the word &lt;strong&gt;page&lt;/strong&gt; to interact with the browser. We can also use the method &lt;strong&gt;.toHaveText&lt;/strong&gt; to validate the result and create assertions. Playwright is not only incredibly user-friendly for developers, but it also boasts a seamless functionality that requires no additional dependencies or extra libraries in order to work perfectly in a variety of scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;p&gt;JavaScript's developers find Cypress easy to understand because the tests are similar to unit tests in JavaScript with libraries like &lt;strong&gt;jest&lt;/strong&gt;. Cypress may be limiting and restrictive for automation QA professionals who prefer to have full control over their workflow and do not rely on the UI for test inspection and execution. Cypress only works with JavaScript, so it's hard to compare it with Playwright, which is popular among other developers.&lt;br&gt;
Selenium has a high flexibility and I can combine it with my favorite libraries. Once the project is established, we can enhance the test structure, streamline the main framework, and optimize code reuse. This approach is favored by many developers. &lt;/p&gt;

&lt;p&gt;UltimateQA posted a survey about the user experience for these frameworks. &lt;a href="https://www.linkedin.com/posts/ultimate-qa_530-engineers-voted-on-their-favorite-developer-activity-7120347995367165952-2IFz?utm_source=share&amp;amp;utm_medium=member_desktop" rel="noopener noreferrer"&gt;Ultimate QA survey&lt;/a&gt;&lt;/p&gt;

&lt;p&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%2Fgbbsf5h9j63ofvebnczy.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%2Fgbbsf5h9j63ofvebnczy.png" alt="UltimateQA Survey" width="762" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The results seem inaccurate because Cypress and Playwright are incredibly user-friendly, yet Selenium remains the most widely used automation library and many developers only have familiarity with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Scenarios vs Best Option
&lt;/h2&gt;

&lt;p&gt;Let's analyze some common scenarios and which framework is a better fit. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A modern application with a small team that uses a new Javascript framework (React.js, Angular, etc..). The team doesn't have experience with automation testing. &lt;strong&gt;For this scenario&lt;/strong&gt;, the best option could be Cypress or Playwright. Developers can easily work with the UI provided for these frameworks and work with JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An app with a modern backend (Node.js, Python, C#, etc.) and modern frontend (React.js, Angular, etc.) with a big team.&lt;br&gt;
&lt;strong&gt;For this scenario&lt;/strong&gt;, we can use all the 3 options. But to work with something modern Playwright could be the best one. We can work with different languages according to the team knowledge and Playwright has been adding extensibility with Selenium.   &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A desktop application using Electron (JavaScript) with node.js backend. &lt;strong&gt;In this case&lt;/strong&gt;, all these frameworks are bad options. At the moment, both Playwright and Cypress offer experimental plugins or extensions for electron, but they may not be suitable for production purposes. We can use &lt;strong&gt;Spectron&lt;/strong&gt;, WebDriverIO or Selenium in conjunction with other libraries to perform our tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;In modern software development, the main test automation tools are Selenium, Cypress, and Playwright. Each of these tools offers unique strengths and weaknesses, catering to different needs within the software testing landscape.&lt;/p&gt;

&lt;p&gt;Selenium, as the oldest and widely used framework, excels in supporting multiple languages and browsers, making it ideal for end-to-end testing. Cypress, with its modern approach, stands out for in-browser testing, simplicity, and efficiency in integration and unit testing. Playwright is a versatile automation tool that excels in multiple browser support, parallel test execution, and automating advanced tasks like mobile device emulation.&lt;/p&gt;

&lt;p&gt;The popularity metrics, including downloads, stars, and contributors on GitHub, depict Playwright's recent surge, surpassing Selenium in community appreciation. However, Selenium remains a top choice for many teams.&lt;/p&gt;

&lt;p&gt;Ultimately, the choice of test automation tool depends on project requirements, team expertise, and the application being tested.&lt;/p&gt;

&lt;p&gt;In my opinion, Playwright will continue growing, and it is a modern and fast tool. I see a great projection for Playwright in the future.&lt;/p&gt;

&lt;p&gt;If you want to try the demos and access the repo, click on the following link:&lt;br&gt;
&lt;a href="https://github.com/Mteheran/AutomationDemos" rel="noopener noreferrer"&gt;https://github.com/Mteheran/AutomationDemos&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>selenium</category>
      <category>cypress</category>
      <category>playwright</category>
    </item>
    <item>
      <title>Discussion: What are the best alternative cloud providers?</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Wed, 24 Jan 2024 21:49:22 +0000</pubDate>
      <link>https://dev.to/mteheran/discussion-what-are-the-best-alternative-cloud-providers-3nd</link>
      <guid>https://dev.to/mteheran/discussion-what-are-the-best-alternative-cloud-providers-3nd</guid>
      <description>&lt;p&gt;It's clear that AWS, Azure and GCP are the most used and popular cloud providers around the world. We can add Alibaba Cloud to this list because they have a high demand in the market. &lt;/p&gt;

&lt;p&gt;I know some other options less popular that we can use for some scenarios:&lt;/p&gt;

&lt;p&gt;Cloudinary: Used for video and image (media content)&lt;br&gt;
Oracle Cloud: Databases and storage&lt;br&gt;
Netlify: Web services and applications&lt;br&gt;
IBM Cloud: Compute, integration and storage&lt;/p&gt;

&lt;p&gt;What of these alternative cloud providers do you use?&lt;br&gt;
What other cloud providers do you know, and how was your experience?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Adding Branch Name To The Commit Message In Git Using Hooks</title>
      <dc:creator>Miguel Teheran</dc:creator>
      <pubDate>Tue, 16 Jan 2024 17:25:10 +0000</pubDate>
      <link>https://dev.to/mteheran/adding-branch-name-to-the-commit-message-in-git-using-hooks-35o0</link>
      <guid>https://dev.to/mteheran/adding-branch-name-to-the-commit-message-in-git-using-hooks-35o0</guid>
      <description>&lt;p&gt;Git Hooks is an amazing tool to automate actions before or after executing a git command. Some common scenarios where we can use hooks are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate the format (using eslint for example) before a commit&lt;/li&gt;
&lt;li&gt;Validate the commit message format&lt;/li&gt;
&lt;li&gt;Update a version of a file or settings&lt;/li&gt;
&lt;li&gt;Add a default text in the commit message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will learn how to add as a default text the branch name in the commit message. Creating a new branch for each new story and naming it after the associated ticket or story number is crucial for maintaining a well-organized and structured development process. This way, you can do things like automatically move the ticket to "doing" status when the branch is created or create a link between the user story and each commit in the branch.&lt;/p&gt;

&lt;p&gt;Some examples of user story numbers in Jira or other bug trackers are:&lt;/p&gt;

&lt;p&gt;U-0001&lt;br&gt;
COMP-0001&lt;br&gt;
STORY-001&lt;/p&gt;

&lt;p&gt;To create our hook for adding the branch name in the commit message we need to navigate to the hooks' folder in our projects.&lt;/p&gt;

&lt;p&gt;Navigate to your folder's project and open .git folder and then hooks folder. There you will find some default templates to create your own hook. &lt;/p&gt;

&lt;p&gt;Example on macOS:&lt;/p&gt;

&lt;p&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%2Ftsofvg4pe9l1wkmdxo33.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%2Ftsofvg4pe9l1wkmdxo33.png" alt="List of git hooks" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you have to create a file with the name prepare-commit-msg. Prepare commit message is the action executed before setting the message in the commit. &lt;/p&gt;

&lt;p&gt;Within prepare-commit-msg file you need to add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# prepending commit message.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BRANCHES_TO_SKIP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;BRANCHES_TO_SKIP&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;master develop release&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git symbolic-ref &lt;span class="nt"&gt;--short&lt;/span&gt; HEAD&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="p"&gt;##*/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;BRANCH_EXCLUDED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCHES_TO_SKIP&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="nv"&gt;$BRANCH_NAME&lt;/span&gt;&lt;span class="s2"&gt;$"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BRANCH_IN_COMMIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="nv"&gt;$BRANCH_NAME&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BRANCH_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$BRANCH_EXCLUDED&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 1 &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$BRANCH_IN_COMMIT&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 1 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"1s/^/&lt;/span&gt;&lt;span class="nv"&gt;$BRANCH_NAME&lt;/span&gt;&lt;span class="s2"&gt; - /"&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="k"&gt;fi
&lt;/span&gt;Bash

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In line number 13 (&lt;code&gt;sed -i.bak -e "1s/^/$BRANCH_NAME - /" $1&lt;/code&gt;), you can see how the branch name is set. You can add more default text or words after the branch name. In this case, we only have a dash.&lt;/p&gt;

&lt;p&gt;By utilizing this configuration, all you have to do is input your message, and it will automatically include the branch name at the start of the commit message.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
