LostCarPark Drupal Blog: Drupal Advent Calendar day 14 - DDEV

Drupal Advent Calendar day 14 - DDEV james Thu, 12/14/2023 - 07:00 Image removed.

It’s day 14, and we’re wrapping up the second week with a big topic. Ryan Price (liberatr) joins us to talk about DDEV, the local development environment.

When you first boot up your computer and start working on a local copy of your site, what does that look like? Is it easy? Is it a chore? (please tell me you’re working locally if you’re doing any theme or module development)

If you got a new laptop tomorrow, would you know how to get your local copies of your sites running on that machine? The idea of setting up a new machine for development used to scare me. Now that I use docker-based tools…

Tags

Tag1 Consulting: Gander: Performance Testing Made Easy

Join us for an update on Gander, the automated performance testing framework making waves in Drupal Core. Developed by Tag1 Consulting and the Google Chrome team, Gander is set to transform how we approach performance testing. In this Tag1 Team Talk Mariano Crivello, Nat Catchpole, and Michael Meyers share the story behind Gander's development. Learn how it's simplifying performance testing for developers, reducing the burden on maintainers, and becoming a game-changer for organizations using Drupal. Part one of our two-part series dives into Gander's history, benefits, and roadmap. Stay tuned for part two, where we'll give you a hands-on demo of Gander in action. Ready to level up your Drupal game? Dive into the Gander story now! Links: - Gander Announcement: The Future of Drupal Performance & Scalability - Google’s Core Web Vitals - Core Web Vitals: Google & Tag1 Improving Drupal’s Performance, User Experience, and Your Bottom Line - from DrupalCon Pittsburgh --- For a transcript of this...

Read more michaelemeyers Wed, 12/13/2023 - 05:00

DrupalEasy: How best to handle "Unsafe usage of new static()" PHPStan errors

Image removed.As a Drupal module developer, if you're as big of a fan of PHPStan as I am, then you'll no doubt have run across the Unsafe usage of new static() error that PHPStan throws when analyzing code at level 0. In this article I will describe what causes this error and provide four possible solutions, weighing the pros and cons of each.

Generally, this will occur in a create() method when you are injecting a dependency into a class using either ContainerFactoryPluginInterface or ContainerInjectionInterface using the common (simplified) Drupal pattern of:

class baseClass { public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->moduleHandler = $module_handler; } public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), ); } }

Basically, PHPStan is warning you that there could be an issue if the class is extended and the new class overrides the constructor with different arguments. For example, if the Token service class is added:

class newClass extends baseClass { public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token, ModuleHandlerInterface $module_handler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->token = $token; $this->moduleHandler = $module_handler; } }

At this point, when newClass is instantiated by the container, it will fail because its inherited create() method no longer matches its overridden constructor. This is bad.

Now, this coding pattern is all over Drupal core and contributed modules, and we are generally very careful about breaking things (thank you, automated tests.) Regardless, PHPStan isn't cool with it, so let's look at some alternatives. 

Dig hole in sand, stick head in it

Easiest, but probably not a good long-term solution.

PHPStan provides the ability for certain errors to be ignored, and this is definitely a good candidate for ignoring. Additionally, it is simple enough to do with a quick addition to your phpstan.neon configuration file:

parameters: level: 0 paths: - web/modules ignoreErrors: - '#Unsafe usage of new static\(\)#'

Generally, I'm not a big fan of ignoring any code quality issues, whether they are from phpcs, PHPStan or any other code quality tool.

Pros

  • PHPStan error goes away

Cons

  • That nagging feeling that you really didn't fix anything.

Prevent others from extending the class

Easiest for custom code, with limitations.

If using new static is only an issue when the class is extended, then why not just prevent the class from being extended with the addition of the final keyword?

final class baseClass { … }

This definitely solves the issue, and in many cases, is a valid solution. I almost always use final when writing a custom module - especially when I am in control of the code base.

Using final in core or a contributed module is a bit trickier, as in most cases the assumption does have to be made that someone somewhere is going to extend that class for reasons you haven't thought of. Being the co-maintainer of several contributed modules, I'm experimenting with using it - to see if anyone opens an issue letting me know that it is blocking them in some way or another. Time will tell.

Pros

  • PHPStan is happy.
  • Code protection against someone extending the class and not properly overriding the constructor and create() methods (if necessary).

Cons

  • The class cannot be extended, possibly limiting its usefulness.

Change new static to new self

Most correct, but with potential repercussions.

Recommended by a Drupal.org documentation page, but with little explanation, this change looks like this (from our example above:)

public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new self( $configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), ); }

In this case, if the class is extended and the constructor is overridden, then the code will always fail unless the create() method is also overridden. Curiously, the documentation page also suggests adding final to the class. I suspect that the documentation page should be updated, but I'm not confident enough in what is the best way to handle this to make a suggestion. Yet.

Pros

  • PHPStan is happy.
  • This is probably the "most correct" solution.

Cons

  • While the class can be extended, less experienced developers might not always recognize that they must override the create() method when overriding the constructor, potentially leading to a bug that can be tricky to figure out. For example, if the create() method isn't overridden, then the result would be that the base class is created and not the (expected) extended class. 

Make the constructor final

Similar to marking the entire class "final".

I haven't spotted this potential solution in a Drupal community discussion, but on the PHPStan blog, one of the suggestions is to just make the constructor final. Again updating our code sample from above:

final public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->moduleHandler = $module_handler; }

This seems like a slightly more flexible solution than making the entire class final or changing from new static to new self, but still would limit anyone extending the class. Maybe this is a reasonable middle-of-the-road solution? I haven't seen it implemented in Drupal yet.

This method would allow the class to be extended, but the constructor wouldn't be allowed to be overridden - which means no dependency changes can be made. Obviously, this limits what extended classes would be able to do.

Similar to this method, the blog post also suggested adding the constructor signature to an interface, which would have the same effect of locking it down so that it cannot be changed.

Pros

  • PHPStan is happy.
  • Code protection against someone extending the class and not properly overriding the constructor and create() methods by not allowing those methods to be overridden. 

Cons

  • If the constructor can't be overridden, then while the class can be extended, its dependencies cannot be changed, potentially limiting its usefulness. 

Summary

So where does that leave us? Hopefully, with the ability to make a more informed decision on how to handle this particular PHPStan error. As I mentioned above, I'm not a big fan of ignoring PHPStan errors, so for now, I'll be adding final most of the time 😉.

Additional reading

Thanks to Professional Module Development course alumni James Shields and Hanane Kacemi as well as Ryan Price for reviewing this blog post.

LostCarPark Drupal Blog: Drupal Advent Calendar day 13 - Mentoring

Drupal Advent Calendar day 13 - Mentoring james Wed, 12/13/2023 - 07:00 Image removed.

It’s day 13 and we’ve fewer than half of the doors remaining. For today’s door we’re taking a break from modules to talk about mentoring with Anto Jose (antojose).

I would like to use this calendar day to tell you about my experience mentoring at DrupalCons.

I signed up for mentoring at DrupalCon Lille, not because I thought of myself particularly as mentoring material, but because of the joy I found years back, when trying to help some people get their first taste of contributing, first during DrupalCon Asia 2016, and then during DrupalCon Amsterdam 2019, and then in a couple of online…

Tags

Salsa Digital: Sharyn Clarkson on CivicTheme at the ACT Drupal Meetup

Image removed.ACT Drupal Meetup September 2023 At the September Drupal Meetup in the ACT, Sharyn presented on adopting an open source design system — CivicTheme .  In her presentation, she set the scene, talking about the now retired Australian Government Design System (AGDS) and GovCMS’ original commitment to that design system. She then moves onto CivicTheme and GovCMS’ plans for the adoption of CivicTheme for new builds and rebuilds.  View Sharyn’s presentation below: About CivicTheme CivicTheme is  an open-source, WCAG-compliant, technology-agnostic design system, UI kit and Drupal theme. It can be used for ‘straight’ Drupal websites or GovCMS websites. Earlier this year it was recognised as part of the Digital Transformation Agency’s Australian Government Architecture (AGA).

Drupal Association blog: Update on Drupal’s response to the EU’s proposed Cyber Resilience Act

This post is a follow up on the collaboration between Drupal and other FOSS projects in response to the proposed CRA legislation in the EU. You can read our original joint letter here.

The Drupal Association has continued to participate in weekly calls with other open source projects leaders hosted by Open Forum Europe to discuss the proposed Cyber Resiliency Act (CRA) in the EU. 

The EU legislators are now reconciling several different draft versions of the regulation, and incorporating stakeholder recommendations into a new draft to be advanced through the legislative process.

For the past several months multiple constituent groups within the EU have shared draft versions of the text, soliciting feedback from a variety of stakeholders in government, industry, and the open source community. 

The Open Forum Europe group reviewed several of those draft pieces being reconciled by legislators and offered detailed input and recommendations. One of the major goals was to ensure that the obligations of the CRA don't fall as an undue burden on individuals, non-profits, non-commercial entities, etc., and to forestall unintended consequences that might curtail corporate participation in open source projects. 

The Drupal Association together with the other projects represented in this process strongly believes that Free and Open Source Software is more secure software, and wanted to ensure that this legislation would not stifle the growth of the FOSS movement.

Some of the many areas we focused our recommendations on were: 

Criteria for obligation under the regulation

  • Preventing redundant obligations on open source software caused by use across multiple entities, and ensuring that appropriate obligations for larger entities are not unfairly enforced on smaller ones. 
  • Avoiding tying obligations to the rate of the release cycle which could create a chilling effect on innovation. 
  • Further clarifying that individual contributors as natural persons do not invoke regulatory obligations by participating in open source projects.
  • Encouraging a process that will allow alignment of obligations internationally, so that it will be easier for global communities to meet all their regulatory obligations.

Defining commerciality

  • Improving the text's definition of 'commerciality' - to help ensure that open source projects and the non-profit foundations that support them are not unintentionally punished for the maturity of their development process or the effectiveness of their fundraising activities. 

Risk assessment 

  • Portions of the regulation depend on the concept of risk assessment and the evaluation of security issues 'low' or 'high' risk, 'known vulnerabilities', 'exploitability,' etc. We noted that these definitions must be carefully considered, transparent, standardized, and have room to be refined post-enactment. 
  • We also raised examples of why the method of remediation of known vulnerabilities might vary depending on each project’s approach, suggesting that this should not be too rigidly defined. 

Open Source Stewardship

  • The regulation introduces the concept of an Open Source Steward, a legal entity that can be said to hold responsibility and accountability for an open source project.
  • This creates a category for obligations separate from those of 'software manufacturers' with a level of flexibility appropriate for open source.
  • However, we noted some potential pitfalls in discrepancies between the definition of stewardship and the authority those steward organizations might have over their projects (see for example, collaborative/decentralized projects).

Collaborative/Decentralized Projects

  • Most regulatory language assumes a central entity with responsibility and accountability. Open source projects are often collaborative and decentralized. We provided several recommendations for defining 'collaborative' projects and flagged some concerns with use of the term 'decentralized' in their regulatory definition. 
  • The primary goal of our recommendations was to avoid inducing obligations (or the risk of fines) on entities that do not necessarily have formal legal relationships with each other nor formal 'ownership' of the software projects they are participating in. 

… and many more recommendations, as well. 

What comes next?

When the draft versions have been reconciled by the EU legislature and the new text is publicly available we'll share with the community. The legislative process will then move form the main body to the standards and implementation details created by the act. 

LN Webworks: Important Announcement: LN Webworks Is Now A Certified Drupal Migration Partner

Image removed.

Drupal 7 is going to retire. Yes, you heard it right! 

Our buddy Drupal 7 is going to retire on January 05, 2025. It has been a trusted CMS partner for thousands of websites but you know, in a space that is forever changing, upgrading to the latest version is not just an optional thing anymore. Your Drupal project must use the most up-to-date version of Drupal for security and performance reasons. 

There won’t be any security release, bug fixes, community support, or addition of new features in Drupal 7 anymore. So it is time to say goodbye to our Drupal 7 buddy as Drupal 10 is here already, loaded with lots of new features & better security for your project. 

We know you may think there is still so much time left. But our dear friend, As you know Preparation is the key to success, and now is the right time to make a successful migration plan for your Drupal site. 

And you know the good news ? 😀

LN Webworks is now a " Drupal Association’s Certified Drupal Migration Partner

The Drop Times: Component-Based Design Using Single Directory Components (SDC) in Drupal

Since recently, Drupal has been using the experimental SDC (Single Directory Components) module. This module aims to bring Drupal front-end development closer to component-based design, a paradigm that in recent years has gained momentum, but was not easy to implement in previous versions of Drupal. In this guide, we will explain what SDC is and how it works, how it can benefit you, how it integrates with other internal and external tools, what its potential is, and how it could even revolutionize the way we work the Drupal front-end.

LostCarPark Drupal Blog: Drupal Advent Calendar day 12 ECA (Event - Condition - Action)

Drupal Advent Calendar day 12 ECA (Event - Condition - Action) james Tue, 12/12/2023 - 07:00 Image removed.

It’s day 12, marking the half way point in the Advent Calendar, and behind today’s door is a module that opens a whole world of possibility for Drupal site builders. We are joined by Michael Lenahan (michaellenahan) to tell us about the ECA module.

A gentle introduction to the ECA module

The reason I chose to write about this module for the Advent Calendar is that I was recommended to look into it by one of my colleagues at work.

It’s one of those modules that really changes the way you think about Drupal … in this case, especially how Drupal can be better for site-builders and those who are not…

Tags

Specbee: How to Navigate Automation Testing with the Power of Selenium and Python

Automation testing is indispensable for anyone involved in software or web applications. Developers love it because it makes the development process smoother, boosts code reliability, and speeds up feedback. Testers get a break as automation takes care of repetitive tasks, easing stress. Business clients save big on costs, thanks to time savings and reduced testing expenses, leading to improved efficiency and financial gains. It's a win-win all around! Selenium, the open-source testing framework for automating web browser interactions, is a powerful cross-browser testing tool that is widely used for functional testing. While it supports multiple programming languages like C++, Java, and C#, Python's readability and simplicity make it user-friendly for writing and maintaining test scripts, enhancing the overall efficiency of the testing process. In this article, we’ll dig deeper into automation testing and how you can use Selenium with Python for automated testing. What is Automation Testing Automation testing is a software testing technique used to automate the validation process or functionality of software to ensure it meets the requirements before releasing it to production. With the help of automation testing, large and repetitive test cases like regression and sanity testing can be made faster by reducing considerable human tester's effort and also achieving quality testing.Automation testing uses scripted sequences executed with the help of automation testing tools. It executes the scripts written to validate the functionalities, compares the results, and produces the Test results report. What can be automated? 1. Stable web applications.2. Applications with minimal changes.3. Repetitive testing like Sanity/ Regression testing. What cannot be automated? 1. Unstable applications (having many open issues/ frequent major changes).2. Automation will not be suitable for projects that are in the under-development stage because it will consume a considerable amount of time and resources to update and maintain the automation test scripts.3. To test a few applications that require specific attention and subject matter expertise. Manual testing will be suitable for these types of testing rather than automated testing.4. CAPTCHA – this requires human intervention to identify the correct match to pass it which is not possible by automation.5. Visual Testing – Applications that require you to validate how they display to the end users, which will need end-user experience that automaton scripts cannot fulfill. What is Selenium Selenium is an automation testing tool to validate the functional and non-functional requirements of web applications.  Selenium is one of the widely used automation testing tools because:  It is an open-source test automation tool. It can be coded in multiple languages like Java, Python, Javascript, C# etc. Selenium covers cross-browser testing like Chrome, Mozilla, Edge, and Safari. It can run using different IDEs like Pycharm, Eclipse, and Visual Studio. Different frameworks are available like Unit Testing, Pytest, and Robot along with keyword-driven or data-driven or hybrid frameworks. Using Selenium with Python As mentioned previously, Selenium accepts various scripting languages to automate the test scripts. Python is the most popular scripting language amongst them because: It is easy to learn and understand, and easier to code due to simple and clean syntax. The code flow of Python is easy to understand as it uses indentation instead of Curley braces at the start and end of the blocks. Python is easy to construct as it uses simple English words and is less verbose than other programming languages. The world is moving towards AI with Machine learning and Python plays a crucial role in implementing them. Installing Python  To install, you can visit their site, and then download and install the latest version of Python. Once Python is installed successfully, you will need to set Python home into system variables. Next, copy the path of python.exe and Script folder locations to: >> system environment variables>>Advanced>>Environment variables >> Add new path. PIP is a Standard package manager for Python (like jars in Java). It allows you to install and manage additional packages which are not part of Python's standard library. Pycharm Installation Pycharm is one of the editor tools used to script the test steps using Selenium with Python. It can be installed by following the steps mentioned below. Download Pycharm here. Download the community edition. Once downloaded and installed successfully, create a new project. Right-click on the project and add a new Python file (this will create a “.py” extension) Start writing your Python program. Browser Invocation To start web automation testing, browser invocation is the first step and this can be achieved with the below syntax based on the browser. For Edge browser: obj = Service() driver = webdriver.Edge(service = obj) driver.get(“webpage url”)For Chrome browser: obj = Service() driver = webdriver.Chrome(service = obj) driver.get(“webpage url”)For Firefox browser: obj = Service() driver = webdriver.Firefox(service = obj) driver.get(“webpage url”)For Safari browser: obj = Service() driver = webdriver.Safari(service = obj) driver.get(“webpage url”)Basic Selenium automation functionalities These functionalities form the foundation for creating Selenium test scripts and are crucial for automating interactions with web applications. Window Maximize: This will maximize the browser window. driver.maximize_window() Window Minimize(): This will minimize the browser window. driver.minimize_window() Page title: This will get the current page title. driver.title Page URL: This will get the current page URL. driver.current_url Closing the current window: This will close the current opened window driver.close() Closing the entire browser: This will close the entire browser opened by the automation  driver.quit() Refresh the current page: This will refresh the current browser driver.refresh() Moving to next screen: This will help to move next to previous screen. driver.forward() Moving to previous screen: This will help to move back to previous screen. driver.back() Selenium Locators Locators enable testers to identify and select the HTML DOM elements to act on. These locators help Selenium WebDriver interact with the specific elements needed for testing or automation.  Here are some common types of Selenium locators: Locating by ID: It is used to identify an element using the ID attribute. There may or may not be ID available for all elements but if it is available, it should be unique. Syntax:  find_element(By.ID, “value”) Locating by NAME: It is used to identify an element using the Name attribute Syntax:  find_element(By.NAME, “value”) Locating by Link Text: It is used to identify a link using link text. It is applicable only for the text having hyperlinks. Syntax:  find_element(By.LINK_TEXT, “value”) Locating by Partial Link Text: It is used to identify the link's partial text. It is applicable only for the text having hyperlinks. Syntax:  find_element(By.PARTIAL_LINK_TEXT, “value”) Locating by CSS_Selector: It is used to locate an element using the CSS selector. Syntax:  driver.findElement(By.cssSelector, “tagname[attribute=‘value’]”) Locating by XPATH: It is used to locate an element using XPath query. Syntax:  driver.findElement(By.cssSelector, “//tagname[@ttribute=‘value’]”) Headless mode: Running the application in invisible state(backend) Syntax:  oj = webdriver.ChromeOptions()oj.add_argument("--start-maximized")oj.add_argument('--headless')  Keyboard data – input: Input data needed to provide on run from the keyboard. Syntax: driver.get(input("Enter the application URL: ")) Final Thoughts By understanding the basics of Selenium automation functionalities, including browser invocation, key WebDriver commands, and the significance of locators, testers, and developers can harness the power of automation to create effective and reliable test scripts. If you're looking for a Drupal development company to seamlessly integrate these automation practices into your web projects, explore the possibilities with Specbee.