Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛 Bug]: [java] PageFactory.initElements overrides final fields #14474

Closed
mk868 opened this issue Sep 4, 2024 · 6 comments
Closed

[🐛 Bug]: [java] PageFactory.initElements overrides final fields #14474

mk868 opened this issue Sep 4, 2024 · 6 comments
Labels
A-needs-triaging A Selenium member will evaluate this soon! C-java Java Bindings I-defect Something is not working as intended

Comments

@mk868
Copy link
Contributor

mk868 commented Sep 4, 2024

What happened?

The PageFactory.initElements(element, this) method overrides all object's fields, including assigned final fields.
I think this behavior is not correct - final fields should not be changed by reflection.

Even IntelliJ hints that the assigned final fields should not change:
image

The problem occurs in the selenium-support artifact

  • It is not related to the browser vendor or browser version

Proposed solution:

  • The DefaultFieldDecorator should ignore final fields when decorating objects.
  • Additionally: the DefaultFieldDecorator should also ignore static fields when decorating objects.

How can we reproduce the issue?

index.html

<div class="card">
    <h2>Title 1</h2>
    <p>Description 1</p>
</div>
<div class="card">
    <h2>Title 2</h2>
    <p>Description 2</p>
</div>
<div class="card">
    <h2>Title 3</h2>
    <p>Description 3</p>
</div>

MainApp.java

import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

import java.io.File;

public class MainApp {

    public static void main(String[] args) throws InterruptedException {
        var options = new FirefoxOptions();
        options.setBinary("/snap/firefox/current/usr/lib/firefox/firefox");
        var webDriver = new FirefoxDriver(options);

        webDriver.get(new File("index.html").toURI().toString());

        Thread.sleep(1000);

        var cards = webDriver.findElements(By.cssSelector(".card")).stream()
                .map(CardComponent::new)
                .toList();

        for (var card : cards) {
            System.out.println("Card title: '" + card.getTitle() + "' description: '" + card.getDescription() + "'");
        }

        webDriver.close();
    }
}

CardComponent.java

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

public class CardComponent extends Component {

    @FindBy(css = "h2")
    private WebElement title;
    @FindBy(css = "p")
    private WebElement description;

    protected CardComponent(WebElement element) {
        super(element);
    }

    public String getTitle() {
        return title.getText();
    }

    public String getDescription() {
        return description.getText();
    }
}

Component.java

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;

public abstract class Component {

    private final WebElement element;

    protected Component(WebElement element) {
        this.element = element;
        PageFactory.initElements(element, this);
        if (this.element != element) {
            throw new IllegalStateException("this.element != element");
        }
    }
}

Relevant log output

Exception in thread "main" java.lang.IllegalStateException: this.element != element
	at Component.<init>(Component.java:12)
	at CardComponent.<init>(CardComponent.java:12)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
	at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
	at MainApp.main(MainApp.java:20)


### Operating System

Linux, Windows 

### Selenium version

java 4.24.0

### What are the browser(s) and version(s) where you see this issue?

Firefox 129.0.2

### What are the browser driver(s) and version(s) where you see this issue?

geckodriver 0.34.0

### Are you using Selenium Grid?

_No response_
@mk868 mk868 added I-defect Something is not working as intended A-needs-triaging A Selenium member will evaluate this soon! labels Sep 4, 2024
Copy link

github-actions bot commented Sep 4, 2024

@mk868, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

@mk868
Copy link
Contributor Author

mk868 commented Sep 4, 2024

If the bug and the proposed solution are confirmed, I can contribute a fix

@pujagani pujagani added the C-java Java Bindings label Sep 9, 2024
@pujagani
Copy link
Contributor

pujagani commented Sep 9, 2024

Thank you for reporting the issue and proposing a solution.
@diemol Are we open to receiving contributions for the support packages?

@diemol
Copy link
Member

diemol commented Sep 9, 2024

I don't think so. We are trying to phase out that package.

@diemol
Copy link
Member

diemol commented Nov 5, 2024

In the long term, we want to remove most (all?) the support package content and redirect people to plugins or frameworks built on top of Selenium. Hence, I am closing this.

@diemol diemol closed this as not planned Won't fix, can't repro, duplicate, stale Nov 5, 2024
Copy link

github-actions bot commented Dec 5, 2024

This issue has been automatically locked since there has not been any recent activity since it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-needs-triaging A Selenium member will evaluate this soon! C-java Java Bindings I-defect Something is not working as intended
Projects
None yet
Development

No branches or pull requests

3 participants