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

typeText seems only to work on last element in a list of rows #2123

Closed
jimwhurr opened this issue Feb 13, 2018 · 7 comments
Closed

typeText seems only to work on last element in a list of rows #2123

jimwhurr opened this issue Feb 13, 2018 · 7 comments
Assignees
Labels
STATE: Auto-locked An issue has been automatically locked by the Lock bot. SYSTEM: hammerhead TYPE: bug The described behavior is considered as wrong (bug).
Milestone

Comments

@jimwhurr
Copy link

Are you requesting a feature or reporting a bug?

Reporting an issue/bug

What is the current behavior?

In a list of rows containing multiple elements only the last row is properly selected when using .nth()

What is the expected behavior?

The element is selected and allows input using typeText.
(This works on the last row in the list)

How would you reproduce the current behavior (if this is a bug)?

I have recreated the issue with the html page and test code, below.

P.S. I have about 100 or so test cases for the app that work perfectly :)

Provide the test code and the tested page URL (if applicable)

Tested page URL:
`

<title>Bug Example</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css"
            integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy"
            crossorigin="anonymous">
</head>
<body>
    <main  id="main-page" role="main" class="container">

        <h3>Managed Users</h3>

        <div id="u-user-list">
            <ul id="user-list" style="list-style-type: none; padding: 0;">
                <div>
                    <li class="row mb-1" tabindex=-1>
                        <input type="email" class="form-control user-email col-sm-6" value="user1.test@test.com" readonly>
                        <input type="text" class="form-control time-extension col-sm-4" placeholder="minutes" disabled/>
                        <button type="button" class="btn btn-secondary extend-button col-sm-2" disabled>Do it</button>
                        <input type="hidden" class="user-id" value="5a7eef48ad671f35c88679ac">
                    </li>
                </div>
                <div>
                    <li class="row mb-1" tabindex=-1>
                        <input type="email" class="form-control user-email col-sm-6" value="user2.test@test.com" readonly>
                        <input type="text" class="form-control time-extension col-sm-4" placeholder="minutes" disabled/>
                        <button type="button" class="btn btn-secondary extend-button col-sm-2" disabled>Do it</button>
                        <input type="hidden" class="user-id" value="5a7eef5cad671f35c88679b6">
                    </li>
                </div>
            </ul>
        </div>    

        <div class="mb-2">&nbsp;</div>

        <div id="alert-park" tabindex=-1></div>

    </main>

    <!-- Bootstrap 4 Scripts -->
    
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"
            integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
            crossorigin="anonymous"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
            integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
            crossorigin="anonymous"></script>
    
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js"
            integrity="sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4"
            crossorigin="anonymous"></script>    

    <!-- logic -->
    <script type="text/javascript">

        function createAlert(severity, message) {
            let html = `<div class="alert alert-${severity} alert-dismissible fade show" role="alert">`;
            html += message;
            html += '<button type="button" class="close" data-dismiss="alert" aria-label="Close">';
            html += '<span aria-hidden="true">&times;</span>';
            html += '</button>';
            html += '</div>';
            $('#alert-park').append(html);
        }

        let row = -1;

        // enable controls when row clicked
        $('.row').click(function() {
            const old = row;
            row =  $('.row').index( this );

            // has row changed?
            if (row != old && old != -1) {
                // disable old row
                $('.time-extension').eq(old).prop( "disabled", true );
                $('.time-extension').eq(old).removeClass('active');
                $('.extend-button').eq(old).prop( "disabled", true );
                $('.extend-button').eq(old).removeClass('active');
            }
            $('.time-extension').eq(row).prop( "disabled", false );
            $('.time-extension').eq(row).addClass('active');
            $('.extend-button').eq(row).prop( "disabled", false );
            $('.extend-button').eq(row).addClass('active');
            $('.time-extension').focus();
        });

        // extend the time :)
        $('.extend-button').click( function() {

            $('.alert').alert('close');

            // check valid time
            const xtime =  $('.time-extension').eq(row).val();

            console.log('row: ' + row + ' time: ' + xtime);

            if ( !xtime || (xtime < -240 || xtime > 240) ) {
                createAlert('danger', 'invalid extension period');
                return;
            }

            const id = $('.user-id').eq(row).val();
            console.log('button ' + row + ' _id:' + id + ' clicked');

            //***** obviously this won't work without the back-end
            //***** if run stand-alone then get rid of this and the
            //***** alert checking from test(s)
            /*
            $.ajax( `../../user/extend/${id}/${xtime}`, {
                type: 'PUT',
                data: {}
            })
            .done( function(res) {
                createAlert('success', 'succesfully updated for user ' +  $('.user-email').eq(row).val() + ', time left now ' + res.time + ' minutes');
                $('.time-extension').eq(row).val('');
                $('.time-extension').eq(row).prop( "disabled", true );
                $('.extend-button').eq(row).prop( "disabled", true );
                $('#alert-park').show();

            })
            .fail(function( jqXHR, textStatus, error ) {
                if (jqXHR.responseJSON) {
                    createAlert('danger',jqXHR.responseJSON.message);
                }
                else {
                    createAlert('danger', 'operation failed due to a network error');
                }
                $('#alert-park').show();
            });
            */

            // stand-alone, just pretend it succeeded.
            createAlert('success', 'succesfully updated for user ' +  $('.user-email').eq(row).val() + ', time left now ' + '20' + ' minutes');
            $('.time-extension').eq(row).val('');
            $('.time-extension').eq(row).prop( "disabled", true );
            $('.extend-button').eq(row).prop( "disabled", true );
            $('#alert-park').show();
        });
    </script>           

</body>
` Test code
`import Page from './extend.page-objects';
import { Selector, ClientFunction, Role } from 'testcafe';

const sessionStorageSet = ClientFunction((key, value) => sessionStorage.setItem(key, value));
const pageUrl = 'http://localhost:3000/issue.html'; 

fixture `ADMINS page`
    .page(pageUrl)
    .beforeEach(async t => {
        await sessionStorageSet('account', '5a7c3003dc4f71deb51e6247');
        await sessionStorageSet('owner', 'test.account@test.com');
        //await t.navigateTo(pageUrl);
    });

const page = new Page();

test('Should enable the time and button when row selected', async t => {
    
    await t
        .click(Selector('.time-extension').nth(0))
        .expect(Selector('.time-extension').nth(0).hasAttribute('disabled')).notOk()
        .expect(Selector('.extend-button').nth(0).hasAttribute('disabled')).notOk()
        .expect(Selector('.time-extension').nth(0).hasClass('active')).ok()
        .expect(Selector('.extend-button').nth(0).hasClass('active')).ok()
});

test('Should enable the time and button when row selected', async t => {
    
    await t
    .click(Selector('.time-extension').nth(1))
    .expect(Selector('.time-extension').nth(1).hasAttribute('disabled')).notOk()
    .expect(Selector('.extend-button').nth(1).hasAttribute('disabled')).notOk()
    .expect(Selector('.time-extension').nth(1).hasClass('active')).ok()
    .expect(Selector('.extend-button').nth(1).hasClass('active')).ok()
});       

test('Should allow the entry of an extension period in first', async t => {

    // This test does NOT work :( it fails with '' does not deeply equal '20'
    //
    // It does not seem to activate the input properyl and, hence, it fails 
    // with '' does not deeply equal '20'
    //
    // Note: I have just discovered this brilliant tool. So these tests are
    // being created retrospectively. All the code that drives the page is
    // working as it should when used maually.

    await t
        .click(Selector('.time-extension').nth(0))
        .typeText(Selector('.time-extension').nth(0), "20")

        .expect(Selector('.time-extension.active').value).eql("20")

});

test('Should allow the entry of an extension period in last', async t => {

    // This test (same as above only on 2nd row) DOES work, but only if
    // the element is the last (irrespective of the number in the list,
    // obviously it has to be nth(0) in a one item list)
    await t
        .click(Selector('.time-extension').nth(1))
        .typeText('.time-extension.active', "20")
        .expect(Selector('.time-extension.active').value).eql('20')

    await t
        .click(Selector('.extend-button').nth(1))
        .expect(Selector('.time-extension.active').value).eql('')
        .expect(Selector(".alert").exists).ok()
        .expect(Selector(".alert").nth(0).innerText).contains('succesfully updated for user user2.test@test.com, time left now');
});
`

Specify your

  • operating system: Windows 10
  • testcafe version: 0.18.6
  • node.js version: v8.9.0
@AlexanderMoskovkin AlexanderMoskovkin added the TYPE: bug The described behavior is considered as wrong (bug). label Feb 13, 2018
@AlexanderMoskovkin
Copy link
Contributor

AlexanderMoskovkin commented Feb 13, 2018

Hi @jimwhurr,

I've reproduced the issue. We'll investigate it

@AlexanderMoskovkin
Copy link
Contributor

@miherlosev @LavrovArtem I've reproduced it under the hammerhead-playground. Please take a look at this

@jimwhurr
Copy link
Author

Thanks

@Farfurix
Copy link
Contributor

I'm working on this

@AlexanderMoskovkin
Copy link
Contributor

It's the same problem as in the #2037. Will be fixed once we update testcafe-hammerhead.

@LavrovArtem
Copy link
Contributor

The fix is published in testcafe@0.19.2-dev20180316.

@lock
Copy link

lock bot commented Mar 28, 2019

This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests. We recommend you ask TestCafe API, usage and configuration inquiries on StackOverflow.

@lock lock bot added the STATE: Auto-locked An issue has been automatically locked by the Lock bot. label Mar 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Mar 28, 2019
kirovboris pushed a commit to kirovboris/testcafe-phoenix that referenced this issue Dec 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
STATE: Auto-locked An issue has been automatically locked by the Lock bot. SYSTEM: hammerhead TYPE: bug The described behavior is considered as wrong (bug).
Projects
None yet
Development

No branches or pull requests

4 participants