form input tag name values changed when moving from M6 to M7

9 views
Skip to first unread message

ben

unread,
Nov 5, 2009, 11:50:01 AM11/5/09
to Lift
Hi,

I was running 1.1-M6 with 2.7.6 with run.mode=test, and had written a
bunch of acceptance tests using Cucumber.
I just upgraded to 1.1-M7 with 2.7.7 and all the name values of form
input tags have changed, failing all my tests :(

Name value with 1.1-M6 + 2.7.6
f00000000010000001_77444531b59f74f18fbde8c81a40a22e862a00cb

Name value with 1.1-M7 + 2.7.7
f00000000010000001_1bceef1fd31e439accaa8462e3dfd1942e1a05ea

Can anyone shed any light on :

1) How are these ids generated
2) Will they always change when we upgrade liftweb/scala versions ?

Cheers,
Ben

David Pollak

unread,
Nov 5, 2009, 4:46:15 PM11/5/09
to lif...@googlegroups.com
On Thu, Nov 5, 2009 at 8:50 AM, ben <b...@primrose.org.uk> wrote:

Hi,

I was running 1.1-M6 with 2.7.6 with run.mode=test, and had written a
bunch of acceptance tests using Cucumber.
I just upgraded to 1.1-M7 with 2.7.7 and all the name values of form
input tags have changed, failing all my tests :(

D'oh.
 

Name value with 1.1-M6 + 2.7.6
f00000000010000001_77444531b59f74f18fbde8c81a40a22e862a00cb

Name value with 1.1-M7 + 2.7.7
f00000000010000001_1bceef1fd31e439accaa8462e3dfd1942e1a05ea

Can anyone shed any light on :

1) How are these ids generated

def formFuncName: String = if (Props.testMode) {
    val bump: Long = ((_formGroup.is openOr 0) + 1000L) * 10000L
    val num: Int = formItemNumber.is
    formItemNumber.set(num + 1)
    import _root_.java.text._
    val prefix: String = new DecimalFormat("00000000000000000").format(bump + num)
    "f" + prefix + "_" + Helpers.hashHex((new Exception).getStackTrace.toList.take(10).map(_.toString).mkString(","))
  } else {
    _formGroup.is match {
      case Full(x) => Helpers.nextFuncName(x.toLong * 10000L)
      case _ => Helpers.nextFuncName
    }
  }

 
2) Will they always change when we upgrade liftweb/scala versions ?

It's based on the stack trace (10 frames), so I think so.  I'm open to other mechanisms of generating stable identifiers, so if you've got something that will generate something stable and unique, changing things is cool with me.
 

Cheers,
Ben





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

ben

unread,
Nov 10, 2009, 2:36:16 PM11/10/09
to Lift
Hi,

Bear in mind that I'm a newbie Lifter, so I won't have the knowledge
of why certain choices were made or the knock on effects of changing
how things work in Lift ...

From my perspective (ie automatically testing a form on a page via
Cucumber), I'm not sure the unique id (as in unique id across all
forms in a webapp) is required. All I need is a unique id for a given
form on a page.
For my needs, the following line alone will provide that :
val prefix: String = new DecimalFormat("00000000000000000").format
(bump + num)

Is there a reason I'm not understanding for why a unique id provided
by the stack trace is required ?

Cheers,
Ben


Timothy Perrett

unread,
Nov 10, 2009, 2:53:22 PM11/10/09
to lif...@googlegroups.com
If Lift is running in test mode the element names should be static, right?

Cheers, Tim

Jeppe Nejsum Madsen

unread,
Nov 10, 2009, 3:33:46 PM11/10/09
to lif...@googlegroups.com
Timothy Perrett <tim...@getintheloop.eu> writes:

> If Lift is running in test mode the element names should be static, right?

Only for the same version of Lift. As David wrote in a (this?) thread,
when in test mode, the id is basically a hash of the stack trace. So
when lift is updated, the ids (most likely) change and you'll have to
update the test cases....not so nice :-)

/Jeppe

Timothy Perrett

unread,
Nov 10, 2009, 3:47:38 PM11/10/09
to Lift
Sorry I should have read the rest of the thread rather than replying
via email - just trying to help but should have kept quiet!

Cheers, Tim

On Nov 10, 8:33 pm, Jeppe Nejsum Madsen <je...@ingolfs.dk> wrote:

ben

unread,
Nov 10, 2009, 5:36:12 PM11/10/09
to Lift
Which brings us back to my original point ... how can we preserve
acceptance tests ?
Do we need to have a stack-trace hash on the form ids or can we have a
non-unique-id-through-the-webapp but unique to the form in order to
achieve this.
My newbie knowledge of Lift suggests we can, but I don't have enough
of a big picture view of Lift to give a conclusive answer ...

David Pollak

unread,
Nov 11, 2009, 12:15:01 PM11/11/09
to lif...@googlegroups.com
On Tue, Nov 10, 2009 at 2:36 PM, ben <b...@primrose.org.uk> wrote:

Which brings us back to my original point ... how can we preserve
acceptance tests ?
Do we need to have a stack-trace hash on the form ids or can we have a
non-unique-id-through-the-webapp but unique to the form in order to
achieve this.

This presents another problem for your tests.  If we assign a monotonically increasing number to each form field, your tests will break if you (1) insert a test or (2) if the number of forms on a page increases or decreases.  Also, having the same ID for items on multiple pages will cause all sorts of problems for testing because you'll be stomping on previously generated fields.

I'll see if I can do something to isolate the hash generation to application-level stuff so you don't get any Lift or Scala stuff in there so as long as your app's call stack is stable, you'll have a stable identifier.  Please open a ticket at http://github.com/dpp/liftweb/issues referring to this thread and I'll try to get to it next week.
 
My newbie knowledge of Lift suggests we can, but I don't have enough
of a big picture view of Lift to give a conclusive answer ...

ben

unread,
Nov 11, 2009, 3:40:47 PM11/11/09
to Lift
Thanks for the reply David. Below is some code which might suit both
our requirements ...

def locateFirstUserStackElement(stack: Array[StackTraceElement]) :
StackTraceElement = {
stack.foreach(element => {
if (!element.toString.startsWith("net.liftweb")) return
element
})
stack(0)
}

def formFuncName: String = if (Props.testMode) {
val bump: Long = ((_formGroup.is openOr 0) + 1000L) * 10000L
val num: Int = formItemNumber.is
formItemNumber.set(num + 1)
import _root_.java.text._
val prefix: String = new DecimalFormat("00000000000000000").format
(bump + num)
//M7 - "f" + prefix + "_" + Helpers.hashHex((new
Exception).getStackTrace.toList.take(10).map(_.toString).mkString
(",")))
"f" + prefix + "_" +Helpers.hashHex(locateFirstUserStackElement
(new Exception().getStackTrace).getClassName)

Alex Boisvert

unread,
Nov 12, 2009, 4:22:52 PM11/12/09
to lif...@googlegroups.com
Wouldn't it be better to provide a unique identifier directly in the source for all elements that require testing?

And I don't mean somebody inputting a unique id manually everywhere but instead using a text processing tool on your codebase that would automatically inject unique ids where desired.

Low tech but I think it would work better in the long run than hashing stack frames.

alex
Reply all
Reply to author
Forward
0 new messages